|
1 | 1 | cimport cython |
2 | 2 | from cython cimport Py_ssize_t |
3 | | -from cython.parallel cimport ( |
4 | | - prange, |
5 | | -) |
| 3 | +from cython.parallel cimport prange |
6 | 4 | from libc.math cimport ( |
7 | 5 | fabs, |
8 | 6 | sqrt, |
@@ -365,7 +363,7 @@ def nancorr( |
365 | 363 | bint no_nans |
366 | 364 | int64_t nobs = 0 |
367 | 365 | float64_t mean, ssqd, val |
368 | | - float64_t vx, vy, dx, dy, meanx, meany, divisor, ssqdmx, ssqdmy, covxy |
| 366 | + float64_t vx, vy, dx, dy, meanx, meany, divisor, ssqdmx, ssqdmy, covxy, corr_val |
369 | 367 |
|
370 | 368 | N, K = (<object>mat).shape |
371 | 369 | if minp is None: |
@@ -393,7 +391,6 @@ def nancorr( |
393 | 391 | means[j] = mean |
394 | 392 | ssqds[j] = ssqd |
395 | 393 |
|
396 | | - # ONLY CHANGE: Add parallel option to the main correlation loop |
397 | 394 | if use_parallel: |
398 | 395 | for xi in prange(K, schedule="dynamic", nogil=True): |
399 | 396 | for yi in range(xi + 1): |
@@ -427,7 +424,19 @@ def nancorr( |
427 | 424 | else: |
428 | 425 | divisor = (nobs - 1.0) if cov else sqrt(ssqdmx * ssqdmy) |
429 | 426 | if divisor != 0: |
430 | | - result[xi, yi] = result[yi, xi] = covxy / divisor |
| 427 | + if cov: |
| 428 | + result[xi, yi] = result[yi, xi] = covxy / divisor |
| 429 | + else: |
| 430 | + # ensure that diagonal is exactly 1.0 |
| 431 | + if xi == yi: |
| 432 | + result[xi, yi] = 1.0 |
| 433 | + else: |
| 434 | + corr_val = covxy / divisor |
| 435 | + if corr_val > 1.0: |
| 436 | + corr_val = 1.0 |
| 437 | + elif corr_val < -1.0: |
| 438 | + corr_val = -1.0 |
| 439 | + result[xi, yi] = result[yi, xi] = corr_val |
431 | 440 | else: |
432 | 441 | result[xi, yi] = result[yi, xi] = NaN |
433 | 442 | else: |
@@ -464,7 +473,19 @@ def nancorr( |
464 | 473 | else: |
465 | 474 | divisor = (nobs - 1.0) if cov else sqrt(ssqdmx * ssqdmy) |
466 | 475 | if divisor != 0: |
467 | | - result[xi, yi] = result[yi, xi] = covxy / divisor |
| 476 | + if cov: |
| 477 | + result[xi, yi] = result[yi, xi] = covxy / divisor |
| 478 | + else: |
| 479 | + # For correlation, ensure diagonal is exactly 1.0 |
| 480 | + if xi == yi: |
| 481 | + result[xi, yi] = 1.0 |
| 482 | + else: |
| 483 | + corr_val = covxy / divisor |
| 484 | + if corr_val > 1.0: |
| 485 | + corr_val = 1.0 |
| 486 | + elif corr_val < -1.0: |
| 487 | + corr_val = -1.0 |
| 488 | + result[xi, yi] = result[yi, xi] = corr_val |
468 | 489 | else: |
469 | 490 | result[xi, yi] = result[yi, xi] = NaN |
470 | 491 |
|
|
0 commit comments