* All data is assumed aligned. */
| 64 | * All data is assumed aligned. |
| 65 | */ |
| 66 | NPY_NO_EXPORT void |
| 67 | CDOUBLE_vdot(char *ip1, npy_intp is1, char *ip2, npy_intp is2, |
| 68 | char *op, npy_intp n, void *NPY_UNUSED(ignore)) |
| 69 | { |
| 70 | #if defined(HAVE_CBLAS) |
| 71 | CBLAS_INT is1b = blas_stride(is1, sizeof(npy_cdouble)); |
| 72 | CBLAS_INT is2b = blas_stride(is2, sizeof(npy_cdouble)); |
| 73 | |
| 74 | if (is1b && is2b) { |
| 75 | double sum[2] = {0., 0.}; /* double for stability */ |
| 76 | |
| 77 | while (n > 0) { |
| 78 | CBLAS_INT chunk = n < NPY_CBLAS_CHUNK ? n : NPY_CBLAS_CHUNK; |
| 79 | double tmp[2]; |
| 80 | |
| 81 | CBLAS_FUNC(cblas_zdotc_sub)((CBLAS_INT)n, ip1, is1b, ip2, is2b, tmp); |
| 82 | sum[0] += (double)tmp[0]; |
| 83 | sum[1] += (double)tmp[1]; |
| 84 | /* use char strides here */ |
| 85 | ip1 += chunk * is1; |
| 86 | ip2 += chunk * is2; |
| 87 | n -= chunk; |
| 88 | } |
| 89 | ((double *)op)[0] = (double)sum[0]; |
| 90 | ((double *)op)[1] = (double)sum[1]; |
| 91 | } |
| 92 | else |
| 93 | #endif |
| 94 | { |
| 95 | double sumr = (double)0.0; |
| 96 | double sumi = (double)0.0; |
| 97 | npy_intp i; |
| 98 | |
| 99 | for (i = 0; i < n; i++, ip1 += is1, ip2 += is2) { |
| 100 | const double ip1r = ((double *)ip1)[0]; |
| 101 | const double ip1i = ((double *)ip1)[1]; |
| 102 | const double ip2r = ((double *)ip2)[0]; |
| 103 | const double ip2i = ((double *)ip2)[1]; |
| 104 | |
| 105 | sumr += ip1r * ip2r + ip1i * ip2i; |
| 106 | sumi += ip1r * ip2i - ip1i * ip2r; |
| 107 | } |
| 108 | ((double *)op)[0] = sumr; |
| 109 | ((double *)op)[1] = sumi; |
| 110 | } |
| 111 | } |
| 112 | |
| 113 | |
| 114 | /* |
nothing calls this directly
no test coverage detected