# Path: pyphysim/util/misc.py
# def randn_c(*args: int) -> np.ndarray:
#     """
#     Generates a random circularly complex gaussian matrix.
# 
#     Parameters
#     ----------
#     *args : any
#         Variable number of arguments (int values) specifying the
#         dimensions of the returned array. This is directly passed to the
#         numpy.random.randn function.
# 
#     Returns
#     -------
#     result : np.ndarray
#         A random N-dimensional numpy array (complex dtype) where the `N` is
#         equal to the number of parameters passed to `randn_c`.
# 
#     Examples
#     --------
#     >>> a = randn_c(4,3)
#     >>> a.shape
#     (4, 3)
#     >>> a.dtype
#     dtype('complex128')
# 
#     """
#     # noinspection PyArgumentList
#     return (1.0 / math.sqrt(2.0)) * (np.random.randn(*args) +
#                                      (1j * np.random.randn(*args)))


import math
import numpy as np
from typing import Any, Optional, Tuple, Union
from ..util.misc import randn_c
    """
    Class that generates fading samples from a Raleigh distribution.

    Parameters
    ----------
    shape : int | tuple[int] | None
        The shape of the sample generator. Each time the
        `generate_jakes_samples` method is called it will generate samples
        with this shape. If not provided, then 1 will be assumed.
    """
    def __init__(self, shape: Optional[Union[int, Shape]] = None) -> None:
        super().__init__(shape)

        # Generate first sample
        self.generate_more_samples()

    def generate_more_samples(self, num_samples: Optional[int] = None) -> None:
        """
        Generate next samples.

        Parameters
        ----------
        num_samples : int, optional
            Number of samples (with the provided shape) to generate. If not
            provided it will be assumed to be 1.
        """
        shape = self.shape

        if num_samples is None:
            if shape is None:

# Path: pyphysim/util/misc.py
# def randn_c(*args: int) -> np.ndarray:
#     """
#     Generates a random circularly complex gaussian matrix.
# 
#     Parameters
#     ----------
#     *args : any
#         Variable number of arguments (int values) specifying the
#         dimensions of the returned array. This is directly passed to the
#         numpy.random.randn function.
# 
#     Returns
#     -------
#     result : np.ndarray
#         A random N-dimensional numpy array (complex dtype) where the `N` is
#         equal to the number of parameters passed to `randn_c`.
# 
#     Examples
#     --------
#     >>> a = randn_c(4,3)
#     >>> a.shape
#     (4, 3)
#     >>> a.dtype
#     dtype('complex128')
# 
#     """
#     # noinspection PyArgumentList
#     return (1.0 / math.sqrt(2.0)) * (np.random.randn(*args) +
#                                      (1j * np.random.randn(*args)))


# Path: pyphysim/channels/fading_generators.py
import math
import numpy as np
from typing import Any, Optional, Tuple, Union
from ..util.misc import randn_c

    """
    Class that generates fading samples from a Raleigh distribution.

    Parameters
    ----------
    shape : int | tuple[int] | None
        The shape of the sample generator. Each time the
        `generate_jakes_samples` method is called it will generate samples
        with this shape. If not provided, then 1 will be assumed.
    """
    def __init__(self, shape: Optional[Union[int, Shape]] = None) -> None:
        super().__init__(shape)

        # Generate first sample
        self.generate_more_samples()

    def generate_more_samples(self, num_samples: Optional[int] = None) -> None:
        """
        Generate next samples.

        Parameters
        ----------
        num_samples : int, optional
            Number of samples (with the provided shape) to generate. If not
            provided it will be assumed to be 1.
        """
        shape = self.shape

        if num_samples is None:
            if shape is None:

                self._samples = randn_c()