import torch


def generate_cRM(Y, S):
    """Generate CRM.

    Args:
        Y (torch.Tensor): mixed/noisy stft.
        S (torch.Tensor): clean stft.

    Returns:
        M (torch.Tensor): structed cRM.

    """
    M = torch.zeros(Y.shape)
    epsilon = 1e-8
    # real part
    M_real = (Y[..., 0] * S[..., 0]) + (Y[..., 1] * S[..., 1])
    square_real = (Y[..., 0] ** 2) + (Y[..., 1] ** 2)
    M_real = M_real / (square_real + epsilon)
    M[..., 0] = M_real
    # imaginary part
    M_img = (Y[..., 0] * S[..., 1]) - (Y[..., 1] * S[..., 0])
    square_img = (Y[..., 0] ** 2) + (Y[..., 1] ** 2)
    M_img = M_img / (square_img + epsilon)
    M[..., 1] = M_img
    return M