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