<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def dipole_k(src, rec, depth, res, freq, wavenumber, ab=11, aniso=None, epermH=None, epermV=None, mpermH=None, mpermV=None, verb=2):
 r"""Return the electromagnetic wavenumber-domain field. Calculate the electromagnetic wavenumber-domain field due to infinitesimal small electric or magnetic dipole source(s), measured by infinitesimal small electric or magnetic dipole receiver(s); sources and receivers are directed along the principal directions x, y, or z, and all sources are at the same depth, as well as all receivers are at the same depth. See Also -------- dipole : Electromagnetic field due to an electromagnetic source (dipoles). bipole : Electromagnetic field due to an electromagnetic source (bipoles). fem : Electromagnetic frequency-domain response. tem : Electromagnetic time-domain response. Parameters src, rec : list of floats or arrays Source and receiver coordinates (m):
 [x, y, z]. The x- and y-coordinates can be arrays, z is a single value. The x- and y-coordinates must have the same dimension. The x- and y-coordinates only matter for the angle-dependent factor. Sources or receivers placed on a layer interface are considered in the upper layer. depth : list Absolute layer interfaces z (m); #depth = #res - 1 (excluding +/- infinity). res : array_like Horizontal resistivities rho_h (Ohm.m); #res = #depth + 1. freq : array_like Frequencies f (Hz), used to calculate etaH/V and zetaH/V. wavenumber : array Wavenumbers lambda (1/m) ab : int, optional Source-receiver configuration, defaults to 11. | | electric source | magnetic source | +===============+=======+======+======+======+======+======+======+ | | **x**| **y**| **z**| **x**| **y**| **z**| | | **x** | 11 | 12 | 13 | 14 | 15 | 16 | + **electric** +-------+------+------+------+------+------+------+ | | **y** | 21 | 22 | 23 | 24 | 25 | 26 | + **receiver** +-------+------+------+------+------+------+------+ | | **z** | 31 | 32 | 33 | 34 | 35 | 36 | | | **x** | 41 | 42 | 43 | 44 | 45 | 46 | + **magnetic** +-------+------+------+------+------+------+------+ | | **y** | 51 | 52 | 53 | 54 | 55 | 56 | + **receiver** +-------+------+------+------+------+------+------+ | | **z** | 61 | 62 | 63 | 64 | 65 | 66 | aniso : array_like, optional Anisotropies lambda = sqrt(rho_v/rho_h) (-); #aniso = #res. Defaults to ones. epermH, epermV : array_like, optional Relative horizontal/vertical electric permittivities epsilon_h/epsilon_v (-); #epermH = #epermV = #res. Default is ones. mpermH, mpermV : array_like, optional Relative horizontal/vertical magnetic permeabilities mu_h/mu_v (-); #mpermH = #mpermV = #res. Default is ones. verb : {0, 1, 2, 3, 4}, optional Level of verbosity, default is 2: - 0: Print nothing. - 1: Print warnings. - 2: Print additional runtime and kernel calls - 3: Print additional start/stop, condensed parameter information. - 4: Print additional full parameter information Returns ------- PJ0, PJ1 : array Wavenumber-domain EM responses: - PJ0: Wavenumber-domain solution for the kernel with a Bessel function of the first kind of order zero. - PJ1: Wavenumber-domain solution for the kernel with a Bessel function of the first kind of order one. Examples -------- [ -1.02638329e-08 +4.91531529e-09j -1.05289724e-08 +5.04222413e-09j -1.08009148e-08 +5.17238608e-09j -1.10798310e-08 +5.30588284e-09j -1.13658957e-08 +5.44279805e-09j -1.16592877e-08 +5.58321732e-09j -1.19601897e-08 +5.72722830e-09j -1.22687889e-08 +5.87492067e-09j -1.25852765e-08 +6.02638626e-09j -1.29098481e-08 +6.18171904e-09j] [ 1.79483705e-10 -6.59235332e-10j 1.88672497e-10 -6.93749344e-10j 1.98325814e-10 -7.30068377e-10j 2.08466693e-10 -7.68286748e-10j 2.19119282e-10 -8.08503709e-10j 2.30308887e-10 -8.50823701e-10j 2.42062030e-10 -8.95356636e-10j 2.54406501e-10 -9.42218177e-10j 2.67371420e-10 -9.91530051e-10j 2.80987292e-10 -1.04342036e-09j] """


    # === 1.  LET'S START ============
    t0 = printstartfinish(verb)

    # === 2.  CHECK INPUT ============

    # Check layer parameters (isfullspace not required)
    modl = check_model(depth, res, aniso, epermH, epermV, mpermH, mpermV,
                       False, verb)
    depth, res, aniso, epermH, epermV, mpermH, mpermV, _ = modl

    # Check frequency => get etaH, etaV, zetaH, and zetaV
    f = check_frequency(freq, res, aniso, epermH, epermV, mpermH, mpermV, verb)
    freq, etaH, etaV, zetaH, zetaV = f

    # Check src-rec configuration
    # => Get flags if src or rec or both are magnetic (msrc, mrec)
    ab_calc, msrc, mrec = check_ab(ab, verb)

    # Check src and rec
    src, nsrc = check_dipole(src, 'src', verb)
    rec, nrec = check_dipole(rec, 'rec', verb)

    # Get angle-dependent factor
    off, angle = get_off_ang(src, rec, nsrc, nrec, verb)
    factAng = kernel.angle_factor(angle, ab, msrc, mrec)

    # Get layer number in which src and rec reside (lsrc/lrec)
    lsrc, zsrc = get_layer_nr(src, depth)
    lrec, zrec = get_layer_nr(rec, depth)

    # === 3. EM-FIELD CALCULATION ============

    # Pre-allocate
    if off.size == 1 and np.ndim(wavenumber) == 2:
        PJ0 = np.zeros((freq.size, wavenumber.shape[0], wavenumber.shape[1]),
                       dtype=complex)
        PJ1 = np.zeros((freq.size, wavenumber.shape[0], wavenumber.shape[1]),
                       dtype=complex)
    else:
        PJ0 = np.zeros((freq.size, off.size, wavenumber.size), dtype=complex)
        PJ1 = np.zeros((freq.size, off.size, wavenumber.size), dtype=complex)

    # If <ab> = 36 (or 63), field is zero
    # In `bipole` and in `dipole`, this is taken care of in `fem`. Here we
    # have to take care of it separately
    if ab_calc not in [36, ]:

        # Calculate wavenumber response
        J0, J1, J0b = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth, etaH,
                                        etaV, zetaH, zetaV,
                                        np.atleast_2d(wavenumber), ab_calc,
                                        False, msrc, mrec, False)

        # Collect output
        if J1 is not None:
            PJ1 += factAng[:, np.newaxis]*J1
            if ab in [11, 12, 21, 22, 14, 24, 15, 25]:  # Because of J2
                # J2(kr) = 2/(kr)*J1(kr) - J0(kr)
                PJ1 /= off[:, None]
        if J0 is not None:
            PJ0 += J0
        if J0b is not None:
            PJ0 += factAng[:, np.newaxis]*J0b

    # === 4.  FINISHED ============
    printstartfinish(verb, t0, 1)

    return np.squeeze(PJ0), np.squeeze(PJ1)