Project physical field on pre-computed EOF. More...
#include <pceof.h>
Go to the source code of this file.
Functions | |
int | project_field_eof (double *bufout, double *bufin, double *bufeof, double *singular_value, double missing_value_eof, double *lon, double *lat, double scale, int ni, int nj, int ntime, int neof) |
Subroutine to project a 2D-time field on pre-calculated EOFs. |
Project physical field on pre-computed EOF.
Definition in file project_field_eof.c.
int project_field_eof | ( | double * | bufout, | |
double * | bufin, | |||
double * | bufeof, | |||
double * | singular_value, | |||
double | missing_value_eof, | |||
double * | lon, | |||
double * | lat, | |||
double | scale, | |||
int | ni, | |||
int | nj, | |||
int | ntime, | |||
int | neof | |||
) |
Subroutine to project a 2D-time field on pre-calculated EOFs.
[out] | bufout | Output 2D (neof x ntime) projected bufin field using input eof and singular_value |
[in] | bufin | Input field 3D (ni x nj x ntime) |
[in] | bufeof | EOF of input field 3D (ni x nj x neof) |
[in] | singular_value | Singular value for EOF |
[in] | missing_value_eof | Missing value for bufeof |
[in] | lon | Longitude |
[in] | lat | Latitude |
[in] | scale | Scaling for units to apply before projecting onto EOF |
[in] | ni | Horizontal dimension |
[in] | nj | Horizontal dimension |
[in] | ntime | Temporal dimension |
[in] | neof | EOF dimension |
Definition at line 55 of file project_field_eof.c.
References alloc_error(), DEGTORAD, and EARTH_RADIUS.
Referenced by main(), and wt_downscaling().
00057 { 00073 double norm; /* Normalization factor. */ 00074 double sum_verif_norm; /* Sum to verify normalization. */ 00075 double val; /* Double temporary value */ 00076 double sum; /* Temporary sum */ 00077 00078 double *true_val = NULL; /* 2D matrix of normalized value */ 00079 00080 double variance_bufin; /* Variance of input buffer */ 00081 double tot_variance_bufin = 0.0; /* Total Variance of input buffer */ 00082 double variance_bufout; /* Variance of output buffer */ 00083 double tot_variance_bufout = 0.0; /* Total Variance of output buffer */ 00084 00085 double sum_scal = 0.0; /* EOF scaling factor sum */ 00086 double *scal = NULL; /* EOF Scaling factor */ 00087 double e1n, e2n; /* Scaling factor components */ 00088 00089 int eof; /* Loop counter */ 00090 int i; /* Loop counter */ 00091 int j; /* Loop counter */ 00092 int t; /* Loop counter */ 00093 00094 /*** Project field on EOFs ***/ 00095 00096 /* Allocate memory */ 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 /* Compute norm */ 00103 00104 /* DEBUG */ 00105 /* sum = 0.0; 00106 for (j=0; j<nj; j++) 00107 for (i=0; i<ni; i++) { 00108 eof = 0; 00109 if (bufeof[i+j*ni+eof*ni*nj] != missing_value_eof) 00110 printf("%d %d %d %d %lf\n",(int) sum,i,j,eof,bufeof[i+j*ni+eof*ni*nj]); 00111 if (bufeof[i+j*ni] != missing_value_eof) 00112 sum = sum + 1.0; 00113 } */ 00114 00115 /* Loop over all EOFs */ 00116 for (eof=0; eof<neof; eof++) { 00117 00118 /* Initializing */ 00119 norm = 0.0; 00120 sum_verif_norm = 0.0; 00121 00122 /* Loop over all gridpoints */ 00123 /* Compute the sum of the squared values normalized by the singular value */ 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 /* Compute true value */ 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 /* Verify that the norm is equal to 1.0 */ 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 /* Free memory */ 00150 (void) free(true_val); 00151 (void) free(scal); 00152 return -1; 00153 } 00154 00155 /* Compute EOF scale factor */ 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 // printf("%lf %lf\n",e1n,e2n); 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 // if (eof == 0) 00175 // printf("%d %d lon=%lf %lf %lf\n",i,j,lon[i+j*ni],lat[i+j*ni],scal[i+j*ni]); 00176 } 00177 00178 /* Project field onto EOF */ 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 /* sum += ( bufin[i+j*ni+t*ni*nj] * scale * scal[i+j*ni] / sqrt(norm) * true_val[i+j*ni] );*/ 00185 sum += ( bufin[i+j*ni+t*ni*nj] * scale / sqrt(norm) * true_val[i+j*ni] ); 00186 bufout[t+eof*ntime] = sum; 00187 // printf("%d %d %lf\n",t,eof,sum); 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 /* Verify variance of field */ 00196 /* Should be of the same order */ 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 /* Free memory */ 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 /* Free memory */ 00213 (void) free(true_val); 00214 (void) free(scal); 00215 00216 /* Success status */ 00217 return 0; 00218 }