# Path: pyphysim/reference_signals/zadoffchu.py
# def calcBaseZC(Nzc: int, u: int, q: complex = 0) -> np.ndarray:
#     """
#     Calculate the root sequence of Zadoff-Chu sequences.
# 
#     Parameters
#     ----------
#     Nzc : int
#         The size of the root Zadoff-Chu sequence.
#     u : int
#         The root sequence index.
#     q : complex
#         Any complex number. Usually this is just zero.
# 
#     Returns
#     -------
#     a_u : np.ndarray
#         The root Zadoff-Chu sequence.
#     """
#     # $X = e^\frac{-j \pi u n (n+1)}{\text{Nzc}}$
#     # In fact, 'u' must be lower than the largest prime number below or
#     # equal to Nzc
#     assert (u < Nzc)
# 
#     n = np.arange(Nzc)
#     a_u = np.exp((-1j * np.pi * u * n * (n + 1 + 2 * q)) / Nzc)
#     return a_u
# 
# def get_extended_ZF(root_seq: np.ndarray, size: int) -> np.ndarray:
#     """
#     Cyclic Extend the Zadoff-Chu root sequence to have size equal to
#     `size`.
# 
#     Parameters
#     ----------
#     root_seq : np.ndarray
#         The root Zadoff-Chu sequence. This is a complex numpy array.
#     size : int
#         The size that the sequence should be extended to.
# 
#     Returns
#     -------
#     output : np.ndarray
#         The extended root sequence.
# 
#     Examples
#     --------
#     >>> root_seq = np.array([1, 2, 3, 4, 5])
#     >>> get_extended_ZF(root_seq, 8)
#     array([1, 2, 3, 4, 5, 1, 2, 3])
#     """
#     root_seq_size = root_seq.size
#     if size - root_seq_size > root_seq_size:
#         stack_list = [root_seq]
#         num_full_repeats = (size // root_seq_size)
#         # Repeat the full sequence by this amount
#         stack_list *= num_full_repeats
# 
#         current_size = root_seq_size * num_full_repeats
# 
#         # Append remaining element to achieve the required size
#         stack_list.append(root_seq[0:size - current_size])
# 
#         output = np.hstack(stack_list)
#     else:
#         output = np.hstack([root_seq, root_seq[0:size - root_seq_size]])
# 
#     return output


from typing import List, Optional, Union, cast
from .zadoffchu import calcBaseZC, get_extended_ZF
import numpy as np
        `size` will be used.
    """
    n_sc_PRB = 12  # Number of subcarriers in a PRB in LTE

    def __init__(self,
                 root_index: int,
                 size: Optional[int] = None,
                 Nzc: Optional[int] = None) -> None:
        if size is None and Nzc is None:
            raise AttributeError("Either 'size' or 'Nzc' (or both) must "
                                 "be provided.")
        if size is None:
            size = Nzc
        assert (isinstance(size, int))

        if Nzc is None:
            Nzc = self._get_largest_prime_lower_than_number(size)

        if size < Nzc:
            raise AttributeError("If 'size' and Nzc are provided, "
                                 "then size must be greater than Nzc")

        self._root_index = root_index
        self._seq_array: np.ndarray = None
        self._extended_seq_array: np.ndarray = None  # Extended Zadoff-Chu sequence

        if size > 2 * self.n_sc_PRB:
            # If size is greater then 2 * n_sc_PRB, the root
            # sequence is an extended Zadoff-Chu sequence. First let's
            # compute the Zadoff-Chu sequence.

# Path: pyphysim/reference_signals/zadoffchu.py
# def calcBaseZC(Nzc: int, u: int, q: complex = 0) -> np.ndarray:
#     """
#     Calculate the root sequence of Zadoff-Chu sequences.
# 
#     Parameters
#     ----------
#     Nzc : int
#         The size of the root Zadoff-Chu sequence.
#     u : int
#         The root sequence index.
#     q : complex
#         Any complex number. Usually this is just zero.
# 
#     Returns
#     -------
#     a_u : np.ndarray
#         The root Zadoff-Chu sequence.
#     """
#     # $X = e^\frac{-j \pi u n (n+1)}{\text{Nzc}}$
#     # In fact, 'u' must be lower than the largest prime number below or
#     # equal to Nzc
#     assert (u < Nzc)
# 
#     n = np.arange(Nzc)
#     a_u = np.exp((-1j * np.pi * u * n * (n + 1 + 2 * q)) / Nzc)
#     return a_u
# 
# def get_extended_ZF(root_seq: np.ndarray, size: int) -> np.ndarray:
#     """
#     Cyclic Extend the Zadoff-Chu root sequence to have size equal to
#     `size`.
# 
#     Parameters
#     ----------
#     root_seq : np.ndarray
#         The root Zadoff-Chu sequence. This is a complex numpy array.
#     size : int
#         The size that the sequence should be extended to.
# 
#     Returns
#     -------
#     output : np.ndarray
#         The extended root sequence.
# 
#     Examples
#     --------
#     >>> root_seq = np.array([1, 2, 3, 4, 5])
#     >>> get_extended_ZF(root_seq, 8)
#     array([1, 2, 3, 4, 5, 1, 2, 3])
#     """
#     root_seq_size = root_seq.size
#     if size - root_seq_size > root_seq_size:
#         stack_list = [root_seq]
#         num_full_repeats = (size // root_seq_size)
#         # Repeat the full sequence by this amount
#         stack_list *= num_full_repeats
# 
#         current_size = root_seq_size * num_full_repeats
# 
#         # Append remaining element to achieve the required size
#         stack_list.append(root_seq[0:size - current_size])
# 
#         output = np.hstack(stack_list)
#     else:
#         output = np.hstack([root_seq, root_seq[0:size - root_seq_size]])
# 
#     return output


# Path: pyphysim/reference_signals/root_sequence.py
from typing import List, Optional, Union, cast
from .zadoffchu import calcBaseZC, get_extended_ZF
import numpy as np

        `size` will be used.
    """
    n_sc_PRB = 12  # Number of subcarriers in a PRB in LTE

    def __init__(self,
                 root_index: int,
                 size: Optional[int] = None,
                 Nzc: Optional[int] = None) -> None:
        if size is None and Nzc is None:
            raise AttributeError("Either 'size' or 'Nzc' (or both) must "
                                 "be provided.")
        if size is None:
            size = Nzc
        assert (isinstance(size, int))

        if Nzc is None:
            Nzc = self._get_largest_prime_lower_than_number(size)

        if size < Nzc:
            raise AttributeError("If 'size' and Nzc are provided, "
                                 "then size must be greater than Nzc")

        self._root_index = root_index
        self._seq_array: np.ndarray = None
        self._extended_seq_array: np.ndarray = None  # Extended Zadoff-Chu sequence

        if size > 2 * self.n_sc_PRB:
            # If size is greater then 2 * n_sc_PRB, the root
            # sequence is an extended Zadoff-Chu sequence. First let's
            # compute the Zadoff-Chu sequence.

            self._seq_array = calcBaseZC(Nzc, root_index)  # Zadoff-Chu seq