Repository: opencv/opencv
File: modules/imgproc/src/phasecorr.cpp (C++)

Code before:
    {
        v_float64 v = v_mul(half, v_sub(one, v_cos(v_mul(vcoeff0, vindex))));
        vx_store(wc + c, v);
        vindex = v_add(vindex, delta);
    }
#endif
    for(; c < cols; c++)
        wc[c] = 0.5 * (1.0 - cos(coeff0 * c));

    if(dst.depth() == CV_32F)
    {
        for(int i = 0; i < rows; i++)
        {
            float* dstData = dst.ptr<float>(i);
            double wr = 0.5 * (1.0 - cos(coeff1 * i));
            int j = 0;
#if CV_SIMD_64F || CV_SIMD_SCALABLE_64F
            v_float64 vwr = vx_setall_f64(wr);
            for (; j < cols; j += nlanes32)
            {
                if (j > cols - nlanes32)
                {
                    if (j == 0)
                        break;
                    j = cols - nlanes32;
                }

                v_float64 v0 = v_mul(vwr, vx_load(wc + j));
                v_float64 v1 = v_mul(vwr, vx_load(wc + j + nlanes64));
                vx_store(dstData + j, v_cvt_f32(v0, v1));
            }
#endif
            for(; j < cols; j++)
                dstData[j] = (float)(wr * wc[j]);
        }
    }
    else
    {
        for(int i = 0; i < rows; i++)
        {
            double* dstData = dst.ptr<double>(i);
            double wr = 0.5 * (1.0 - cos(coeff1 * i));
            int j = 0;
#if CV_SIMD_64F || CV_SIMD_SCALABLE_64F
            v_float64 vwr = vx_setall_f64(wr);
            for (; j < cols; j += nlanes64)
            {
                if (j > cols - nlanes64)
                {
                    if (j == 0)
                        break;

Review comment (performance):
What if drop the condition and just use scalar tail for it? IMHO it should fix small performance degradation on arm.

Code after:
    {
        v_float64 v = v_mul(half, v_sub(one, v_cos(v_mul(vcoeff0, vindex))));
        vx_store(wc + c, v);
        vindex = v_add(vindex, delta);
    }
#endif
    for(; c < cols; c++)
        wc[c] = 0.5 * (1.0 - cos(coeff0 * c));

    if(dst.depth() == CV_32F)
    {
        for(int i = 0; i < rows; i++)
        {
            float* dstData = dst.ptr<float>(i);
            double wr = 0.5 * (1.0 - cos(coeff1 * i));
            int j = 0;
#if CV_SIMD_64F || CV_SIMD_SCALABLE_64F
            v_float64 vwr = vx_setall_f64(wr);
            for (; j <= cols - nlanes32; j += nlanes32)
            {
                v_float64 v0 = v_mul(vwr, vx_load(wc + j));
                v_float64 v1 = v_mul(vwr, vx_load(wc + j + nlanes64));
                vx_store(dstData + j, v_cvt_f32(v0, v1));
            }
#endif
            for(; j < cols; j++)
                dstData[j] = (float)(wr * wc[j]);
        }
    }
    else
    {
        for(int i = 0; i < rows; i++)
        {
            double* dstData = dst.ptr<double>(i);
            double wr = 0.5 * (1.0 - cos(coeff1 * i));
            int j = 0;
#if CV_SIMD_64F || CV_SIMD_SCALABLE_64F
            v_float64 vwr = vx_setall_f64(wr);
            for (; j <= cols - nlanes64; j += nlanes64)
            {
                v_float64 v = v_mul(vwr, vx_load(wc + j));
                vx_store(dstData + j, v);
            }
#endif
            for(; j < cols; j++)
                dstData[j] = wr * wc[j];
        }
    }

    // perform batch sqrt for SSE performance gains
    cv::sqrt(dst, dst);