00001 #include "ctypes_def.h"
00002
00003 #if TYPE == FLOAT
00004 #define GAPSTRUCTURE sgapstructure
00005 #define BURG smulti_burg
00006 #define FAHLMAN_ULRYCH sfahlman_ulrych
00007 #define FILL_GAPS sfill_gaps
00008 #define TOEPLITZ_MULT stoeplitz_mult
00009 #define PRECONDITION sprecondition
00010 #define PCG spcg
00011 #define LEVINSON slevinson
00012 #define EPSILON FLT_EPSILON
00013 #elif TYPE == DOUBLE
00014 #define GAPSTRUCTURE dgapstructure
00015 #define BURG dmulti_burg
00016 #define FAHLMAN_ULRYCH dfahlman_ulrych
00017 #define FILL_GAPS dfill_gaps
00018 #define TOEPLITZ_MULT dtoeplitz_mult
00019 #define PRECONDITION dprecondition
00020 #define PCG dpcg
00021 #define LEVINSON dlevinson
00022 #define EPSILON DBL_EPSILON
00023 #elif TYPE == COMPLEXFLOAT
00024 #define GAPSTRUCTURE cgapstructure
00025 #define BURG cmulti_burg
00026 #define FAHLMAN_ULRYCH cfahlman_ulrych
00027 #define FILL_GAPS cfill_gaps
00028 #define TOEPLITZ_MULT ctoeplitz_mult
00029 #define PRECONDITION cprecondition
00030 #define PCG cpcg
00031 #define LEVINSON clevinson
00032 #define EPSILON FLT_EPSILON
00033 #elif TYPE == COMPLEXDOUBLE
00034 #define GAPSTRUCTURE zgapstructure
00035 #define BURG zmulti_burg
00036 #define FAHLMAN_ULRYCH zfahlman_ulrych
00037 #define FILL_GAPS zfill_gaps
00038 #define TOEPLITZ_MULT ztoeplitz_mult
00039 #define PRECONDITION zprecondition
00040 #define PCG zpcg
00041 #define LEVINSON zlevinson
00042 #define EPSILON DBL_EPSILON
00043 #endif
00044
00045 #define PCG_MAXIT n_gap
00046 #define PCG_TOL 1e-6
00047
00048 static int GAPSTRUCTURE(int n, CTYPE *data, int *isgood,
00049 gapped_timeseries *ts, int **data_length,
00050 CTYPE ***good_data, int minpercentage);
00051 static void FILL_GAPS(int n, CTYPE *data, int *isgood, int order, CTYPE *ar_coeff);
00052 static void TOEPLITZ_MULT(int n, CTYPE *x, CTYPE *y, void **data);
00053 static void PRECONDITION(int n, CTYPE *x, CTYPE *y, void **data);
00054
00055
00056
00057
00058
00059 int FAHLMAN_ULRYCH(int n, CTYPE *data_in, int *isgood_in, int minpercentage,
00060 int maxorder, int iterations, int padends,
00061 int *order, CTYPE *ar_coeff_in)
00062 {
00063 #ifndef NDEBUG
00064 int verbose=1;
00065 #else
00066 int verbose=0;
00067 #endif
00068 int i,j, first, last, iter, effective_order;
00069 RTYPE *err ;
00070 gapped_timeseries ts,tsm;
00071 CTYPE **good_data;
00072 int *isgood;
00073 CTYPE *data, nold;
00074 int *data_length;
00075 int *model_gaps, oldorder;
00076 int model_order;
00077 CTYPE *ar_coeff;
00078
00079
00080 if (ar_coeff_in)
00081 ar_coeff = ar_coeff_in;
00082 else
00083 ar_coeff = malloc(maxorder*sizeof(CTYPE));
00084
00085 assert(minpercentage>0 && minpercentage<=100);
00086
00087
00088
00089
00090
00091
00092
00093
00094 if (padends)
00095 {
00096 nold = n;
00097 n = nold + 2*maxorder;
00098 data = calloc(n,sizeof(CTYPE));
00099 isgood = calloc(n,sizeof(int));
00100 memcpy(&data[maxorder],data_in,nold*sizeof(CTYPE));
00101 memcpy(&isgood[maxorder],isgood_in,nold*sizeof(int));
00102 }
00103 else
00104 {
00105 isgood = isgood_in;
00106 data = data_in;
00107 }
00108
00109 oldorder = -1;
00110 model_order = GAPSTRUCTURE(n, data, isgood, &ts, &data_length,
00111 &good_data, minpercentage);
00112 tsm = ts;
00113 model_gaps = malloc(n*sizeof(int));
00114 memcpy(model_gaps, isgood, n*sizeof(int));
00115 for (iter=0; iter<iterations; iter++)
00116 {
00117
00118 if (iter>0)
00119 model_order = GAPSTRUCTURE(n, data, model_gaps, &tsm, &data_length,
00120 &good_data, minpercentage);
00121
00122
00123 model_order = min( model_order,maxorder);
00124
00125
00126
00127
00128
00129 err = (RTYPE *) malloc((model_order+1)*sizeof(RTYPE));
00130
00131 if (verbose)
00132 {
00133 printf("Determining AR(%d) model...",model_order);
00134 fflush(stdout);
00135 }
00136
00137 effective_order = BURG(tsm.m_data, data_length, good_data, model_order,
00138 ar_coeff, err);
00139
00140 if (verbose)
00141 {
00142 printf("done\n");
00143 printf("Specified order = %d, Effective order = %d.\n",
00144 model_order, effective_order);
00145
00146 fflush(stdout);
00147 }
00148
00149 model_order = effective_order;
00150 if (ts.first_is_good)
00151 {
00152 i = 1;
00153 first = max(0,ts.data_int[0].last-(model_order)+1);
00154 last=-1;
00155 }
00156 else
00157 {
00158 i = 0;
00159 first = 0;
00160 last=-1;
00161 }
00162 memcpy(model_gaps, isgood, n*sizeof(int));
00163 while ( i<ts.m_data && last<n-1)
00164 {
00165
00166
00167
00168 while (i<ts.m_data &&
00169 (ts.data_int[i].last-ts.data_int[i].first+1)<(model_order) &&
00170 (i==0 || (ts.data_int[i].first-ts.data_int[i-1].last-1)<model_order)
00171 )
00172 { i++; }
00173
00174
00175 if (i!=0 && (ts.data_int[i].first-ts.data_int[i-1].last)>=model_order)
00176 last = ts.data_int[i-1].last+(model_order)-1;
00177 else if ( i>=ts.m_data-1 )
00178 last = n-1;
00179 else
00180 last = ts.data_int[i].first+(model_order)-1;
00181
00182 if (verbose)
00183 printf("Filling missing data in [ %d : %d ].\n",first,last);
00184
00185 FILL_GAPS(last-first+1, &data[first], &isgood[first],
00186 (model_order), ar_coeff);
00187
00188 first = ts.data_int[i].last-(model_order)+1;
00189 i++;
00190 }
00191
00192 for(i=0; i<ts.m_gap; i++)
00193 {
00194 if ( ts.gap_int[i].last-ts.gap_int[i].first+1 <= model_order)
00195 for (j = ts.gap_int[i].first; j<=ts.gap_int[i].last; j++)
00196 model_gaps[j] = 1;
00197 }
00198 if (verbose)
00199 printf("done\n");
00200 if (iter>0)
00201 {
00202 free(tsm.gap_int); free(tsm.data_int);
00203 }
00204 free(data_length); free(good_data);
00205 free(err);
00206
00207 if (oldorder==model_order || tsm.m_gap==0)
00208 break;
00209
00210 oldorder = model_order;
00211 }
00212 free(ts.gap_int); free(ts.data_int);
00213 memcpy(isgood,model_gaps,n*sizeof(int));
00214 for (i=0;i<n;i++)
00215 if (model_gaps[i]==0)
00216 data[i] = 0;
00217
00218 free(model_gaps);
00219
00220
00221 if (padends)
00222 {
00223 memcpy(data_in, &data[maxorder],nold*sizeof(CTYPE));
00224 memcpy(isgood_in,&isgood[maxorder],nold*sizeof(int));
00225 free(data);
00226 free(isgood);
00227 }
00228
00229 if (ar_coeff_in==NULL)
00230 free(ar_coeff);
00231
00232 if (order)
00233 *order = model_order;
00234
00235 return 0;
00236 }
00237
00238
00239 static void FILL_GAPS(int n, CTYPE *data, int *isgood, int order,
00240 CTYPE *ar_coeff)
00241 {
00242 int iter, idx, i, shift, *gap_idx, *gap_idx_inv, *block;
00243 int n_gap, n_data, n_blocks, maxblock;
00244 CTYPE *rhs, *rhs2, *data_gap, *gamma2, *scratch;
00245 RTYPE rnorm, tol;
00246 void *aarg[3], *marg[3];
00247 CTYPE *gamma;
00248
00249
00250
00251
00252
00253
00254 gamma = (CTYPE *)malloc((order+1)*sizeof(CTYPE));
00255 rhs = (CTYPE *)malloc(2*(n-order)*sizeof(CTYPE));
00256 for (shift = 0; shift<=order; shift++)
00257 {
00258 gamma[shift] = 0;
00259 for (i=0; (i+shift)<=order; i++)
00260 gamma[shift] += 2*CONJ(ar_coeff[i+shift])*ar_coeff[i];
00261
00262 }
00263
00264
00265
00266
00267
00268 gap_idx = (int*)calloc(n,sizeof(int));
00269 gap_idx_inv = (int*)calloc(n,sizeof(int));
00270 block = (int*)calloc(n,sizeof(int));
00271 n_data = 0;
00272 n_gap = 0;
00273 n_blocks = 0;
00274 maxblock = 0;
00275 for (i=0; i<n; i++)
00276 {
00277 if (isgood[i])
00278 {
00279 n_data++;
00280 if (i>0 && !isgood[i-1])
00281 n_blocks++;
00282 }
00283 else
00284 {
00285
00286 gap_idx[i] = n_gap;
00287 gap_idx_inv[n_gap] = i;
00288 n_gap++;
00289 block[n_blocks]++;
00290 if (block[n_blocks] > maxblock)
00291 maxblock = block[n_blocks];
00292 }
00293 }
00294
00295
00296 for (shift=0; (shift+order)<n; shift++)
00297 {
00298 rhs[shift] = 0;
00299 rhs[shift+(n-order)] = 0;
00300 for (i=0; i<=order; i++)
00301 {
00302 if (isgood[i+shift])
00303 {
00304 rhs[shift] -= ar_coeff[order-i]*data[i+shift];
00305 rhs[shift+(n-order)] -= CONJ(ar_coeff[i])*data[i+shift];
00306 }
00307 }
00308 }
00309
00310 rhs2 = (CTYPE *)calloc(n_gap,sizeof(CTYPE));
00311 for (shift=0; (shift+order)<n; shift++)
00312 {
00313 for (i=0; i<=order; i++)
00314 {
00315 if ( !isgood[i+shift] )
00316 {
00317 idx = gap_idx[i+shift];
00318
00319 rhs2[idx] += CONJ(ar_coeff[order-i])*rhs[shift];
00320 rhs2[idx] += ar_coeff[i]*rhs[shift+(n-order)];
00321
00322 }
00323 }
00324 }
00325
00326
00327
00328
00329
00330
00331 data_gap = (CTYPE*)calloc(n_gap,sizeof(CTYPE));
00332 if (n_gap == 1)
00333 data_gap[0] = rhs2[0] / gamma[0];
00334 else
00335 {
00336
00337 aarg[0] = (void *) ℴ
00338 aarg[1] = (void *) gap_idx_inv;
00339 aarg[2] = (void *) gamma;
00340
00341
00342 gamma2 = (CTYPE *) calloc(maxblock,sizeof(CTYPE));
00343 scratch = (CTYPE *) calloc(maxblock,sizeof(CTYPE));
00344 for (i=0; i<=min(order,maxblock-1); i++)
00345 gamma2[i] = gamma[i];
00346 marg[0] = (void *) block;
00347 marg[1] = (void *) gamma2;
00348 marg[2] = (void *) scratch;
00349
00350
00351 memset(data_gap, 0, n_gap*sizeof(CTYPE));
00352 tol = sqrt(order)*PCG_TOL;
00353 iter = PCG(n_gap, PCG_MAXIT+2, tol, TOEPLITZ_MULT,
00354 PRECONDITION, rhs2, data_gap, &rnorm, aarg, marg);
00355 if (rnorm>tol)
00356 fprintf(stderr, "Warning: PCG did not converge. "
00357 "After %d iterations (maxit=%d) the relative"
00358 " residual was %e (tol=%e)\n",
00359 iter, PCG_MAXIT+2, rnorm,tol);
00360
00361
00362
00363
00364
00365 free(scratch); free(gamma2);
00366 }
00367
00368 for (i=0; i<n_gap; i++)
00369 data[gap_idx_inv[i]] = data_gap[i];
00370
00371 free(block); free(gap_idx); free(gap_idx_inv);
00372 free(data_gap); free(gamma); free(rhs); free(rhs2);
00373 }
00374
00375
00376
00377 static int GAPSTRUCTURE(int n, CTYPE *data, int *isgood, gapped_timeseries *ts,
00378 int **data_length, CTYPE ***good_data, int minpercentage)
00379 {
00380 #ifndef NDEBUG
00381 int verbose=1;
00382 #else
00383 int verbose=0;
00384 #endif
00385 int i,j,first;
00386
00387
00388
00389 ts->n_data = 0; ts->m_data = 0;
00390 ts->n_gap = 0; ts->m_gap = 0;
00391 for (i=0; i<n-1; i++)
00392 {
00393 assert(isgood[i]==1 || isgood[i]==0);
00394 if (isgood[i]==1)
00395 {
00396 ts->n_data++;
00397 if (i==0)
00398 {
00399 ts->first_is_good = 1;
00400 ts->m_data++;
00401 }
00402 if (isgood[i+1]==0)
00403 ts->m_gap++;
00404 }
00405 else
00406 {
00407 ts->n_gap++;
00408 if (i==0)
00409 {
00410 ts->first_is_good = 0;
00411 ts->m_gap++;
00412 }
00413 if (isgood[i+1]==1)
00414 ts->m_data++;
00415 }
00416 }
00417 if (isgood[n-1]==1)
00418 ts->n_data++;
00419 else
00420 ts->n_gap++;
00421
00422
00423 if (verbose)
00424 printf("n_data = %d, m_data = %d\nn_gap = %d, m_gap = %d\n",
00425 ts->n_data,ts->m_data,ts->n_gap,ts->m_gap);
00426
00427 assert((isgood[0]==0 && isgood[n-1]==0 && ts->m_gap == ts->m_data+1) ||
00428 (isgood[0]==1 && isgood[n-1]==1 && ts->m_gap == ts->m_data-1) ||
00429 (isgood[0]!=isgood[n-1] && ts->m_gap == ts->m_data));
00430
00431
00432
00433 *good_data = (CTYPE **) malloc(ts->m_data*sizeof(CTYPE *));
00434 *data_length = (int *) malloc(ts->m_data*sizeof(int));
00435 ts->gap_int = (interval *) malloc(ts->m_gap*sizeof(interval));
00436 ts->data_int = (interval *) malloc(ts->m_data*sizeof(interval));
00437
00438
00439
00440 j = 0;
00441 first=0;
00442 if (isgood[0]==1)
00443 {
00444 first=0;
00445 ts->data_int[0].first = 0;
00446 (*good_data)[0] = &data[0];
00447 j++;
00448 }
00449 for (i=0; i<n-1; i++)
00450 {
00451
00452 if (isgood[i]==0 && isgood[i+1]==1)
00453 {
00454 first = i+1;
00455 ts->data_int[j].first = first;
00456 (*good_data)[j] = &(data[i+1]);
00457
00458 j++;
00459 }
00460
00461 if (isgood[i]==1 && isgood[i+1]==0)
00462 {
00463 (*data_length)[j-1] = i-first+1;
00464 ts->data_int[j-1].last = i;
00465 }
00466 }
00467 if (isgood[n-1]==1)
00468 {
00469 (*data_length)[j-1] = n-1-first+1;
00470 ts->data_int[j-1].last = n-1;
00471 }
00472 if (ts->first_is_good)
00473 {
00474 for(j=0; j<ts->m_data;j++)
00475 {
00476 if (j<ts->m_gap)
00477 ts->gap_int[j].first = ts->data_int[j].last+1;
00478 if (j>0)
00479 ts->gap_int[j-1].last = ts->data_int[j].first-1;
00480 }
00481 if (ts->m_data==ts->m_gap)
00482 ts->gap_int[ts->m_gap-1].last = n-1;
00483 }
00484 else
00485 {
00486 ts->gap_int[0].first = 0;
00487 for(j=0; j<ts->m_data;j++)
00488 {
00489 if (j<ts->m_gap)
00490 ts->gap_int[j].last = ts->data_int[j].first-1;
00491 if (j<ts->m_gap-1)
00492 ts->gap_int[j+1].first = ts->data_int[j].last+1;
00493 }
00494 if (ts->m_gap==ts->m_data+1)
00495 ts->gap_int[ts->m_gap-1].last = n-1;
00496 }
00497 return maxorder(ts, *data_length, minpercentage);
00498 }
00499
00500
00501
00502
00503
00504
00505 static void TOEPLITZ_MULT(int n, CTYPE *x, CTYPE *y, void **data)
00506 {
00507 int i,j,order,idx,ii;
00508 int *gap_idx_inv;
00509 CTYPE *r;
00510
00511 order = *((int *) data[0]);
00512 gap_idx_inv = (int *) data[1];
00513 r = (CTYPE *) data[2];
00514
00515 for (i=0; i<n; i++)
00516 y[i] = r[0]*x[i];
00517
00518 for (i=0; i<n; i++)
00519 {
00520 ii = gap_idx_inv[i];
00521 for (j=i+1; j<n; j++)
00522 {
00523 idx = ii-gap_idx_inv[j];
00524 if (idx <= order && idx >= -order)
00525 {
00526 if (idx>=0)
00527 {
00528 y[i] += CONJ(r[idx])*x[j];
00529 y[j] += r[idx]*x[i];
00530 }
00531 else
00532 {
00533 y[i] += r[-idx]*x[j];
00534 y[j] += CONJ(r[-idx])*x[i];
00535 }
00536 }
00537 }
00538 }
00539 }
00540
00541
00542 static void PRECONDITION(int n, CTYPE *b, CTYPE *x, void **data)
00543 {
00544 int i,first,*block;
00545 CTYPE *gamma, *scratch;
00546 block = (int *) data[0];
00547 gamma = (CTYPE *) data[1];
00548 scratch = (CTYPE *) data[2];
00549
00550
00551 for(i=0, first = 0; first<n; first+=block[i], i++)
00552 {
00553 memcpy(scratch,&b[first],block[i]*sizeof(CTYPE));
00554 LEVINSON(block[i],gamma,scratch,&x[first]);
00555 }
00556 }
00557
00558
00559 #undef GAPSTRUCTURE
00560 #undef FAHLMAN_ULRYCH
00561 #undef BURG
00562 #undef FILL_GAPS
00563 #undef TOEPLITZ_MULT
00564 #undef PRECONDITION
00565 #undef PCG
00566 #undef LEVINSON
00567 #undef EPSILON
00568 #include "ctypes_undef.h"