#line 1 "numpy/core/src/umath/loops_unary_complex.dispatch.c.src"

/*
 *****************************************************************************
 **       This file was autogenerated from a template  DO NOT EDIT!!!!      **
 **       Changes should be made to the original source (.src) file         **
 *****************************************************************************
 */

#line 1
/*@targets
 ** $maxopt baseline
 ** sse2 (avx2 fma3) avx512f
 ** neon asimd
 ** vsx2 vsx3
 ** vx vxe
 **/
#define _UMATHMODULE
#define _MULTIARRAYMODULE
#define NPY_NO_DEPRECATED_API NPY_API_VERSION

#include "simd/simd.h"
#include "loops_utils.h"
#include "loops.h"
#include "lowlevel_strided_loops.h"
// Provides the various *_LOOP macros
#include "fast_loop_macros.h"

#line 30
#if NPY_SIMD_F32
NPY_FINLINE npyv_f32
simd_cabsolute_f32(npyv_f32 re, npyv_f32 im)
{
    const npyv_f32 inf = npyv_setall_f32(NPY_INFINITYF);
    const npyv_f32 nan = npyv_setall_f32(NPY_NANF);

    re = npyv_abs_f32(re);
    im = npyv_abs_f32(im);
    /*
     * If real or imag = INF, then convert it to inf + j*inf
     * Handles: inf + j*nan, nan + j*inf
     */
    npyv_b32 re_infmask = npyv_cmpeq_f32(re, inf);
    npyv_b32 im_infmask = npyv_cmpeq_f32(im, inf);
    im = npyv_select_f32(re_infmask, inf, im);
    re = npyv_select_f32(im_infmask, inf, re);
    /*
     * If real or imag = NAN, then convert it to nan + j*nan
     * Handles: x + j*nan, nan + j*x
     */
    npyv_b32 re_nnanmask = npyv_notnan_f32(re);
    npyv_b32 im_nnanmask = npyv_notnan_f32(im);
    im = npyv_select_f32(re_nnanmask, im, nan);
    re = npyv_select_f32(im_nnanmask, re, nan);

    npyv_f32 larger  = npyv_max_f32(re, im);
    npyv_f32 smaller = npyv_min_f32(im, re);
    /*
     * Calculate div_mask to prevent 0./0. and inf/inf operations in div
     */
    npyv_b32 zeromask = npyv_cmpeq_f32(larger, npyv_zero_f32());
    npyv_b32 infmask = npyv_cmpeq_f32(smaller, inf);
    npyv_b32 div_mask = npyv_not_b32(npyv_or_b32(zeromask, infmask));

    npyv_f32 ratio = npyv_ifdivz_f32(div_mask, smaller, larger);
    npyv_f32 hypot = npyv_sqrt_f32(
        npyv_muladd_f32(ratio, ratio, npyv_setall_f32(1.0f)
    ));
    return npyv_mul_f32(hypot, larger);
}
#endif // VECTOR

#line 30
#if NPY_SIMD_F64
NPY_FINLINE npyv_f64
simd_cabsolute_f64(npyv_f64 re, npyv_f64 im)
{
    const npyv_f64 inf = npyv_setall_f64(NPY_INFINITY);
    const npyv_f64 nan = npyv_setall_f64(NPY_NAN);

    re = npyv_abs_f64(re);
    im = npyv_abs_f64(im);
    /*
     * If real or imag = INF, then convert it to inf + j*inf
     * Handles: inf + j*nan, nan + j*inf
     */
    npyv_b64 re_infmask = npyv_cmpeq_f64(re, inf);
    npyv_b64 im_infmask = npyv_cmpeq_f64(im, inf);
    im = npyv_select_f64(re_infmask, inf, im);
    re = npyv_select_f64(im_infmask, inf, re);
    /*
     * If real or imag = NAN, then convert it to nan + j*nan
     * Handles: x + j*nan, nan + j*x
     */
    npyv_b64 re_nnanmask = npyv_notnan_f64(re);
    npyv_b64 im_nnanmask = npyv_notnan_f64(im);
    im = npyv_select_f64(re_nnanmask, im, nan);
    re = npyv_select_f64(im_nnanmask, re, nan);

    npyv_f64 larger  = npyv_max_f64(re, im);
    npyv_f64 smaller = npyv_min_f64(im, re);
    /*
     * Calculate div_mask to prevent 0./0. and inf/inf operations in div
     */
    npyv_b64 zeromask = npyv_cmpeq_f64(larger, npyv_zero_f64());
    npyv_b64 infmask = npyv_cmpeq_f64(smaller, inf);
    npyv_b64 div_mask = npyv_not_b64(npyv_or_b64(zeromask, infmask));

    npyv_f64 ratio = npyv_ifdivz_f64(div_mask, smaller, larger);
    npyv_f64 hypot = npyv_sqrt_f64(
        npyv_muladd_f64(ratio, ratio, npyv_setall_f64(1.0)
    ));
    return npyv_mul_f64(hypot, larger);
}
#endif // VECTOR


/********************************************************************************
 ** Defining ufunc inner functions
 ********************************************************************************/
#line 86
NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(CFLOAT_absolute)
(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
{
#if NPY_SIMD_F32
    npy_intp len = dimensions[0];
    npy_intp ssrc = steps[0] / sizeof(npy_float);
    npy_intp sdst = steps[1] / sizeof(npy_float);

    if (!is_mem_overlap(args[0], steps[0], args[1], steps[1], len) &&
        npyv_loadable_stride_f32(ssrc) && npyv_storable_stride_f32(sdst)
        && steps[0] % sizeof(npy_float) == 0
        && steps[1] % sizeof(npy_float) == 0
    ) {
        const npy_float *src = (npy_float*)args[0];
              npy_float *dst = (npy_float*)args[1];

        const int vstep = npyv_nlanes_f32;
        const int wstep = vstep * 2;
        const int hstep = vstep / 2;

        if (ssrc == 2 && sdst == 1) {
            for (; len >= vstep; len -= vstep, src += wstep, dst += vstep) {
                npyv_f32x2 ab = npyv_load_f32x2(src);
                npyv_f32 r = simd_cabsolute_f32(ab.val[0], ab.val[1]);
                npyv_store_f32(dst, r);
            }
        }
        else {
            for (; len >= vstep; len -= vstep, src += ssrc*vstep, dst += sdst*vstep) {
                npyv_f32 re_im0 = npyv_loadn2_f32(src, ssrc);
                npyv_f32 re_im1 = npyv_loadn2_f32(src + ssrc*hstep, ssrc);
                npyv_f32x2 ab = npyv_unzip_f32(re_im0, re_im1);
                npyv_f32 r = simd_cabsolute_f32(ab.val[0], ab.val[1]);
                npyv_storen_f32(dst, sdst, r);
            }
        }
        for (; len > 0; len -= vstep, src += ssrc*vstep, dst += sdst*vstep) {
            npyv_f32 rl = npyv_loadn_tillz_f32(src, ssrc, len);
            npyv_f32 im = npyv_loadn_tillz_f32(src + 1, ssrc, len);
            npyv_f32 r = simd_cabsolute_f32(rl, im);
            npyv_storen_till_f32(dst, sdst, len, r);
        }
        npyv_cleanup();
        npy_clear_floatstatus_barrier((char*)&len);
        return;
    }
#endif
    UNARY_LOOP {
        const npy_float re = ((npy_float *)ip1)[0];
        const npy_float im = ((npy_float *)ip1)[1];
        *((npy_float *)op1) = npy_hypotf(re, im);
    }
}

#line 86
NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(CDOUBLE_absolute)
(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
{
#if NPY_SIMD_F64
    npy_intp len = dimensions[0];
    npy_intp ssrc = steps[0] / sizeof(npy_double);
    npy_intp sdst = steps[1] / sizeof(npy_double);

    if (!is_mem_overlap(args[0], steps[0], args[1], steps[1], len) &&
        npyv_loadable_stride_f64(ssrc) && npyv_storable_stride_f64(sdst)
        && steps[0] % sizeof(npy_double) == 0
        && steps[1] % sizeof(npy_double) == 0
    ) {
        const npy_double *src = (npy_double*)args[0];
              npy_double *dst = (npy_double*)args[1];

        const int vstep = npyv_nlanes_f64;
        const int wstep = vstep * 2;
        const int hstep = vstep / 2;

        if (ssrc == 2 && sdst == 1) {
            for (; len >= vstep; len -= vstep, src += wstep, dst += vstep) {
                npyv_f64x2 ab = npyv_load_f64x2(src);
                npyv_f64 r = simd_cabsolute_f64(ab.val[0], ab.val[1]);
                npyv_store_f64(dst, r);
            }
        }
        else {
            for (; len >= vstep; len -= vstep, src += ssrc*vstep, dst += sdst*vstep) {
                npyv_f64 re_im0 = npyv_loadn2_f64(src, ssrc);
                npyv_f64 re_im1 = npyv_loadn2_f64(src + ssrc*hstep, ssrc);
                npyv_f64x2 ab = npyv_unzip_f64(re_im0, re_im1);
                npyv_f64 r = simd_cabsolute_f64(ab.val[0], ab.val[1]);
                npyv_storen_f64(dst, sdst, r);
            }
        }
        for (; len > 0; len -= vstep, src += ssrc*vstep, dst += sdst*vstep) {
            npyv_f64 rl = npyv_loadn_tillz_f64(src, ssrc, len);
            npyv_f64 im = npyv_loadn_tillz_f64(src + 1, ssrc, len);
            npyv_f64 r = simd_cabsolute_f64(rl, im);
            npyv_storen_till_f64(dst, sdst, len, r);
        }
        npyv_cleanup();
        npy_clear_floatstatus_barrier((char*)&len);
        return;
    }
#endif
    UNARY_LOOP {
        const npy_double re = ((npy_double *)ip1)[0];
        const npy_double im = ((npy_double *)ip1)[1];
        *((npy_double *)op1) = npy_hypot(re, im);
    }
}


