|
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