| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "na64util/numerical/sums.h" | ||
| 2 | |||
| 3 | #include <math.h> | ||
| 4 | #include <assert.h> | ||
| 5 | #include <stdlib.h> | ||
| 6 | |||
| 7 | /* | ||
| 8 | * Klein's Sum | ||
| 9 | * **********/ | ||
| 10 | |||
| 11 | void | ||
| 12 | 19419 | na64dp_sum_klein_init(na64dp_KleinScorer_t * S) { | |
| 13 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 19419 times.
|
19419 | assert(S); |
| 14 | 19419 | S->s = S->cs = S->ccs = 0.; | |
| 15 | 19419 | } | |
| 16 | |||
| 17 | void | ||
| 18 | 4157609 | na64dp_sum_klein_add( na64dp_KleinScorer_t * S | |
| 19 | , double v ) { | ||
| 20 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4157609 times.
|
4157609 | assert(S); |
| 21 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4157609 times.
|
4157609 | assert( !isnan(v) ); |
| 22 | 4157609 | double c, cc, t = S->s + v; | |
| 23 |
2/2✓ Branch 0 taken 4113472 times.
✓ Branch 1 taken 44137 times.
|
4157609 | if( fabs(S->s) >= fabs(v) ) { |
| 24 | 4113472 | c = (S->s - t) + v; | |
| 25 | } else { | ||
| 26 | 44137 | c = (v - t) + S->s; | |
| 27 | } | ||
| 28 | 4157609 | S->s = t; | |
| 29 | 4157609 | t = S->cs + c; | |
| 30 |
2/2✓ Branch 0 taken 3585638 times.
✓ Branch 1 taken 571971 times.
|
4157609 | if( fabs(S->cs) >= fabs(c) ) { |
| 31 | 3585638 | cc = (S->cs - t) + c; | |
| 32 | } else { | ||
| 33 | 571971 | cc = (c - t) + S->cs; | |
| 34 | } | ||
| 35 | 4157609 | S->cs = t; | |
| 36 | 4157609 | S->ccs += cc; | |
| 37 | 4157609 | } | |
| 38 | |||
| 39 | double | ||
| 40 | 39774 | na64dp_sum_klein_result(const na64dp_KleinScorer_t * S) { | |
| 41 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 39774 times.
|
39774 | assert(S); |
| 42 | 39774 | return S->s + S->cs + S->ccs; | |
| 43 | } | ||
| 44 | |||
| 45 | /* | ||
| 46 | * Pearson's Correlation | ||
| 47 | * ********************/ | ||
| 48 | |||
| 49 | void | ||
| 50 | 1 | na64dp_cov_init( na64dp_Covariance_t * C ) { | |
| 51 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | assert(C); |
| 52 | 1 | C->n = 0; | |
| 53 | 1 | na64dp_sum_klein_init( &(C->xMean) ); | |
| 54 | 1 | na64dp_sum_klein_init( &(C->yMean) ); | |
| 55 | 1 | na64dp_sum_klein_init( &(C->d2x) ); | |
| 56 | 1 | na64dp_sum_klein_init( &(C->d2y) ); | |
| 57 | 1 | na64dp_sum_klein_init( &(C->rS) ); | |
| 58 | 1 | } | |
| 59 | |||
| 60 | void | ||
| 61 | 7 | na64dp_cov_account( na64dp_Covariance_t * C | |
| 62 | , double x, double y ) { | ||
| 63 | /* Increase value count */ | ||
| 64 | 7 | ++(C->n); | |
| 65 | 7 | const double dx1 = x - na64dp_sum_klein_result(&(C->xMean)) | |
| 66 | 7 | , dy1 = y - na64dp_sum_klein_result(&(C->yMean)) | |
| 67 | ; | ||
| 68 | 7 | na64dp_sum_klein_add( &(C->xMean), dx1/(C->n) ); | |
| 69 | 7 | na64dp_sum_klein_add( &(C->yMean), dy1/(C->n) ); | |
| 70 | |||
| 71 | 7 | const double dx2 = x - na64dp_sum_klein_result(&(C->xMean)) | |
| 72 | 7 | , dy2 = y - na64dp_sum_klein_result(&(C->yMean)) | |
| 73 | ; | ||
| 74 | 7 | na64dp_sum_klein_add( &(C->d2x), dx1*dx2 ); | |
| 75 | 7 | na64dp_sum_klein_add( &(C->d2y), dy1*dy2 ); | |
| 76 | /* Compute and update co-moment sum */ | ||
| 77 | 7 | na64dp_sum_klein_add( &(C->rS), dx1*dy2 ); | |
| 78 | 7 | } | |
| 79 | |||
| 80 | double | ||
| 81 | 12 | na64dp_covariance_get( const na64dp_Covariance_t * C ) { | |
| 82 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | if( C->n < 2 ) { |
| 83 | ✗ | return nan("0"); | |
| 84 | } | ||
| 85 | 12 | return na64dp_sum_klein_result(&(C->rS))/(C->n-1.); | |
| 86 | } | ||
| 87 | |||
| 88 | void | ||
| 89 | 1 | na64dp_mcov_init( na64dp_CovarianceMatrix_t * ptr | |
| 90 | , unsigned short d ) { | ||
| 91 | 1 | ptr->d = d; | |
| 92 | 1 | ptr->n = 0; | |
| 93 | 1 | ptr->means = malloc( d*sizeof(na64dp_KleinScorer_t) ); | |
| 94 | 1 | ptr->sqds = malloc( d*sizeof(na64dp_KleinScorer_t) ); | |
| 95 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
|
6 | for( int i = 0; i < d; ++i ) { |
| 96 | 5 | na64dp_sum_klein_init( ptr->means + i ); | |
| 97 | 5 | na64dp_sum_klein_init( ptr->sqds + i ); | |
| 98 | } | ||
| 99 | 1 | const unsigned int nComponents = d*(d+1)/2; | |
| 100 | 1 | ptr->covs = malloc( nComponents*sizeof(na64dp_KleinScorer_t) ); | |
| 101 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 1 times.
|
16 | for( int i = 0; i < nComponents; ++i ) { |
| 102 | 15 | na64dp_sum_klein_init( ptr->covs + i ); | |
| 103 | } | ||
| 104 | 1 | } | |
| 105 | |||
| 106 | void | ||
| 107 | 7 | na64dp_mcov_account( na64dp_CovarianceMatrix_t * M | |
| 108 | 7 | , const double * v ) { | |
| 109 | /* Increase value count */ | ||
| 110 | 7 | ++(M->n); | |
| 111 | /* Compute deviations. | ||
| 112 | * Note: variable length array here. Alternatively one may involve | ||
| 113 | * alloca() call here if current compiler does not support this extension */ | ||
| 114 | 7 | double dV1[M->d] | |
| 115 | 7 | , dV2[M->d] | |
| 116 | ; | ||
| 117 |
2/2✓ Branch 0 taken 35 times.
✓ Branch 1 taken 7 times.
|
42 | for( int i = 0; i < M->d; ++i ) { |
| 118 | /* Deviation prior to mean value modification */ | ||
| 119 | 35 | dV1[i] = v[i] - na64dp_sum_klein_result(M->means + i); | |
| 120 | /* Modify mean value */ | ||
| 121 | 35 | na64dp_sum_klein_add( M->means + i, dV1[i]/(M->n) ); | |
| 122 | /* Deviation after to mean value modification */ | ||
| 123 | 35 | dV2[i] = v[i] - na64dp_sum_klein_result(M->means + i); | |
| 124 | /* Increase cumulative squared deviation sum */ | ||
| 125 | 35 | na64dp_sum_klein_add( M->sqds + i, dV1[i]*dV2[i] ); | |
| 126 | } | ||
| 127 | /* For each unique value pair within a vector (15) */ | ||
| 128 | 7 | int k = 0; | |
| 129 |
2/2✓ Branch 0 taken 35 times.
✓ Branch 1 taken 7 times.
|
42 | for( int i = 0; i < M->d; ++i ) { |
| 130 |
2/2✓ Branch 0 taken 105 times.
✓ Branch 1 taken 35 times.
|
140 | for( int j = i; j < M->d; ++j ) { |
| 131 | 105 | na64dp_sum_klein_add( M->covs + k, dV1[i]*dV2[j] ); | |
| 132 | 105 | ++k; | |
| 133 | } | ||
| 134 | } | ||
| 135 | 7 | } | |
| 136 | |||
| 137 | double | ||
| 138 | 180 | na64dp_mcov( na64dp_CovarianceMatrix_t * M, int i, int j ) { | |
| 139 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 180 times.
|
180 | if( M->n < 2 ) { |
| 140 | ✗ | return nan("0"); | |
| 141 | } | ||
| 142 | 180 | size_t offset = j + i*(M->d * 2 - 1 - i)/2; | |
| 143 | 180 | return na64dp_sum_klein_result( M->covs + offset )/(M->n - 1); | |
| 144 | } | ||
| 145 | |||
| 146 | void | ||
| 147 | 1 | na64dp_mcov_free( na64dp_CovarianceMatrix_t * M ) { | |
| 148 | 1 | free(M->means); | |
| 149 | 1 | free(M->sqds); | |
| 150 | 1 | free(M->covs); | |
| 151 | 1 | } | |
| 152 | |||
| 153 |