import numpy as np


def to_dB(x):
    """A simple function that converts x to dB: ``20*np.log10(x)``"""
    result = np.asarray(20*np.log10(x))
    result[~np.isfinite(result)] = 0
    return result


def from_dB(x):
    """A simple function that converts x in dB to a ratio over 1:
    ``10**(x/20)``

    """
    result = np.power(10, (x/20))
    return result


class MatlabList(list):
    """A list that allows slicing like Matlab.

    eg: ``l[1, 2, slice(3, 5), slice(10, 20, 2)]``

    """
    def __getitem__(self, index):
        output = []
        if isinstance(index, tuple) or isinstance(index, range):
            for i in index:
                if isinstance(i, range):
                    range_list = list(i)
                    for r in range_list:
                        if r not in index:
                            output.append(self[r])
                else:
                    output.append(self[i])
            return output
        else:
            return super().__getitem__(index)


def sdof_modal_peak(w, wr, zr, cr, phi):
    """Return a modal peak generated from the given parameters.

    Parameters
    ----------
    w : ndarray
        An array of omega (angular frequency) values.
    wr : float
        The resonant angular frequency.
    zr : float
        The damping factor.
    cr : float
        The magnitude of the modal constant.
    phi : float
        The phase of the modal constant.

    Returns
    -------
    ndarray
        The modal peak.

    Notes
    -----
    The modal peak is generated by:

    .. math:: \frac{C_r e^(i\phi)}{\omega_r^2 + 2i\zeta_r\omega_r^2 - \omega^2}

    """
    return cr*np.exp(1j*phi) / (wr**2 - w**2 + 2j * zr * wr**2)
