project_field_eof.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include <pceof.h>
00052
00054 int
00055 project_field_eof(double *bufout, double *bufin, double *bufeof, double *singular_value,
00056 double missing_value_eof, double *lon, double *lat, double scale, int ni, int nj, int ntime, int neof)
00057 {
00073 double norm;
00074 double sum_verif_norm;
00075 double val;
00076 double sum;
00077
00078 double *true_val = NULL;
00079
00080 double variance_bufin;
00081 double tot_variance_bufin = 0.0;
00082 double variance_bufout;
00083 double tot_variance_bufout = 0.0;
00084
00085 double sum_scal = 0.0;
00086 double *scal = NULL;
00087 double e1n, e2n;
00088
00089 int eof;
00090 int i;
00091 int j;
00092 int t;
00093
00094
00095
00096
00097 true_val = (double *) malloc(ni*nj * sizeof(double));
00098 if (true_val == NULL) alloc_error(__FILE__, __LINE__);
00099 scal = (double *) malloc(ni*nj * sizeof(double));
00100 if (scal == NULL) alloc_error(__FILE__, __LINE__);
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 for (eof=0; eof<neof; eof++) {
00117
00118
00119 norm = 0.0;
00120 sum_verif_norm = 0.0;
00121
00122
00123
00124 for (j=0; j<nj; j++)
00125 for (i=0; i<ni; i++) {
00126 if (bufeof[i+j*ni+eof*ni*nj] != missing_value_eof) {
00127 val = bufeof[i+j*ni+eof*ni*nj] / singular_value[eof];
00128 norm += (val * val);
00129 }
00130 }
00131
00132
00133 sum = 0.0;
00134 for (j=0; j<nj; j++)
00135 for (i=0; i<ni; i++) {
00136 if (bufeof[i+j*ni+eof*ni*nj] != missing_value_eof) {
00137 val = bufeof[i+j*ni+eof*ni*nj] / ( sqrt(norm) * singular_value[eof] );
00138 true_val[i+j*ni] = val;
00139 sum += val;
00140 sum_verif_norm += (val * val);
00141 }
00142 }
00143
00144
00145 (void) fprintf(stdout, "%s: Verifying the sqrt(norm)=%lf (should be equal to 1) for EOF #%d: %lf\n", __FILE__, sqrt(norm),
00146 eof, sum_verif_norm);
00147 if (fabs(sum_verif_norm) < 0.01) {
00148 (void) fprintf(stderr, "%s: FATAL ERROR: Re-norming does not equal 1.0 : %lf.\nAborting\n", __FILE__, sum_verif_norm);
00149
00150 (void) free(true_val);
00151 (void) free(scal);
00152 return -1;
00153 }
00154
00155
00156 sum_scal = 0.0;
00157 for (j=0; j<nj; j++)
00158 for (i=0; i<ni; i++) {
00159 if (j < (nj-1))
00160 e1n = ( 2.0*M_PI*EARTH_RADIUS/(DEGTORAD*lon[i+j*ni]) ) * fabs( cos( DEGTORAD*(lat[i+(j+1)*ni]-lat[i+j*ni]) ) );
00161 else
00162 e1n = ( 2.0*M_PI*EARTH_RADIUS/(DEGTORAD*lon[i+j*ni]) ) * fabs( cos( DEGTORAD*(lat[i+j*ni]-lat[i+(j-1)*ni]) ) );
00163 if (j < (nj-1))
00164 e2n = ( 2.0*EARTH_RADIUS ) * fabs( cos( DEGTORAD*(lat[i+(j+1)*ni]-lat[i+j*ni]) ) );
00165 else
00166 e2n = ( 2.0*EARTH_RADIUS ) * fabs( cos( DEGTORAD*(lat[i+j*ni]-lat[i+(j-1)*ni]) ) );
00167
00168 scal[i+j*ni] = e1n * e2n;
00169 sum_scal += scal[i+j*ni];
00170 }
00171 for (j=0; j<nj; j++)
00172 for (i=0; i<ni; i++) {
00173 scal[i+j*ni] = sqrt( scal[i+j*ni] * (1.0/sum_scal) );
00174
00175
00176 }
00177
00178
00179 for (t=0; t<ntime; t++) {
00180 sum = 0.0;
00181 for (j=0; j<nj; j++)
00182 for (i=0; i<ni; i++)
00183 if (bufeof[i+j*ni+eof*ni*nj] != missing_value_eof)
00184
00185 sum += ( bufin[i+j*ni+t*ni*nj] * scale / sqrt(norm) * true_val[i+j*ni] );
00186 bufout[t+eof*ntime] = sum;
00187
00188 }
00189
00190 variance_bufout = gsl_stats_variance(&(bufout[eof*ntime]), 1, ntime);
00191 tot_variance_bufout += variance_bufout;
00192 variance_bufin = gsl_stats_variance(&(bufin[eof*ntime]), 1, ntime);
00193 tot_variance_bufin += variance_bufin;
00194
00195
00196
00197 (void) fprintf(stdout, "%s: Verifying square-root of variance (should be the same order): %lf %lf\n", __FILE__,
00198 sqrt(variance_bufout), singular_value[eof]);
00199 (void) fprintf(stdout, "%s: %lf\n", __FILE__, sqrt(variance_bufout) / singular_value[eof]);
00200 if ( (sqrt(gsl_stats_variance(&(bufout[eof*ntime]), 1, ntime)) / singular_value[eof]) >= 10.0) {
00201 (void) fprintf(stderr, "%s: FATAL ERROR: Problem in scaling factor! Variance is not of the same order. Verify configuration file scaling factor.\nAborting\n", __FILE__);
00202
00203 (void) free(true_val);
00204 (void) free(scal);
00205 return -1;
00206 }
00207 }
00208
00209 (void) fprintf(stdout, "%s: Comparing total variance of field before %lf and after %lf projection onto EOF: %% of variance remaining: %lf\n",
00210 __FILE__, tot_variance_bufin, tot_variance_bufout, tot_variance_bufout / tot_variance_bufin * 100.0);
00211
00212
00213 (void) free(true_val);
00214 (void) free(scal);
00215
00216
00217 return 0;
00218 }