calculate_fs2.c
来自「最大似然估计算法」· C语言 代码 · 共 131 行
C
131 行
#include "timeseries.h"double calculate_fs2(double *time, int n_data, int *index, int *f1_count) { int i, j, k, n; int error, count; int year1, year2, leap1, leap2; int n_attempt = 9; int n_sample = 7; int *bad, *idt; double s, dp, min_dt, max_dt, scale, t, ds; double median, fs, rdt; double *dt, *tmp; double sample[] = {0.041666666, 1.0, 2.0, 7.0, 14.0, 30.4375, 365.25}; double daily[] = {365.24219, 0.0, 0.0, 0.0, 365.0, 365.25, 365.24219, 365.2564, 365.259635}; dt = (double *) calloc((size_t) (n_data-1), sizeof(double)); tmp = (double *) calloc((size_t) (n_data-1), sizeof(double)); bad = (int *) calloc((size_t) (n_data-1), sizeof(int)); idt = (int *) calloc((size_t) (n_data-1), sizeof(int)); error = 0; for (j = 0; j < n_data-1; j++) { dt[j] = time[j+1] - time[j]; tmp[j] = dt[j]; if (dt[j] <= 0.0) bad[error++] = j; if (j == 0) min_dt = dt[j]; else min_dt = dt[j] < min_dt ? dt[j] : min_dt; } if (error) { fprintf(stderr, " calculate_fs : file is not in ascending"); fprintf(stderr, " time order or has duplicated points\n"); for (j = 0; j < error; j++) { fprintf(stderr, " : t[%d] - t[%d] = %f\n", bad[j]+1, bad[j], dt[bad[j]]); } exit(EXIT_FAILURE); } free(bad); /******************************************************************/ /* First find out the number of decimal places in the time stamps */ /******************************************************************/ dp = 0.0; do { dp += 1.0; s = 0.0; scale = pow(10.0,dp); for (j = 0; j < n_data; j++) { t = rint(time[j] * scale) / scale; s += ((t-time[j])*(t-time[j])); } s = sqrt(s / (double) n_data); } while (s > 1e-13); /************************************************************************/ /* The 1e-13 was arrived at partly from trial and error and it is */ /* related to the numerical precision of the computer, meaning it */ /* can only really distinguish up to 12 decimal places */ /* For a specified decimal place, the differences between the full */ /* value and the "clipped" value should form a uniform distribution */ /* between -0.5 / 10^dp and 0.5 / 10^dp. Therefore the square root of */ /* the sum of the differences squared should have a mean equal to */ /* (N / 12 / 10^(2*dp))^0.5. The difficultly is for small time series */ /* say less the 250 the error on the mean is quite large and could */ /* possibly overlap with the dp level below. A better method will be */ /* developed later, its not really critical at this stage, for well */ /* defined time series. */ /************************************************************************/ count = n_data - 1; qsort((char *)tmp, (size_t)count, sizeof(double), comp_double_asc); if ((int)fmod(count,2) == 1) { median = tmp[(count+1)/2 - 1]; } else { median = ( tmp[count/2-1] + tmp[count/2] ) / 2.0; } free(tmp); n = lrint(median / min_dt); rdt = fmod(median,min_dt); if (n > 1) { if (rdt < 0.1) { median /= (double) n; } else { fprintf(stderr, " Error : calculate_fs2 : min_dt and median disagree"); fprintf(stderr, " by non-integer value (remainder %f) greater than 0.1\n", rdt); exit(EXIT_FAILURE); } } count = 0; error = 0; index[0] = 0; for (j = 0; j < n_data-1; j++) { idt[j] = lrint( dt[j] / median); if (idt[j] == 0) { fprintf(stderr, " Error : calculate_fs2 : dt (%f) is smaller", dt[j]); fprintf(stderr, " than median (%f) at %4d,%4d (%f %f) \n",median, j, j+1, time[j], time[j+1]); error++; } if (idt[j] == 1) count++; index[j+1] = index[j] + idt[j]; } if (error) { fprintf(stderr, "%d\n", lrint(median / min_dt)); exit(EXIT_FAILURE); } fs = 1.0 / median / 365.24219 / 24.0 / 3600; (*f1_count) = count; free(dt); free(idt); return(fs);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?