pceof.h File Reference

Include file for Principal Components and EOF related calculations library. More...

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <math.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/mman.h>
#include <gsl/gsl_statistics.h>
#include <misc.h>
Include dependency graph for pceof.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define _GNU_SOURCE
 GNU extensions.
#define TRUE   1
 TRUE value macro is 1.
#define FALSE   0
 FALSE value macro is 0.
#define EARTH_RADIUS   6371229.0
 Earth Radius.
#define DEGTORAD   M_PI/180.0
 Convert Degrees to Radian.

Functions

void normalize_pc (double *norm_all, double *first_variance, double *buf_renorm, double *bufin, int neof, int ntime)
 Normalize a 2D variable by the norm of the first column of the first dimension and recompute the new norm.
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.

Detailed Description

Include file for Principal Components and EOF related calculations library.

Definition in file pceof.h.


Define Documentation

#define _GNU_SOURCE

GNU extensions.

Definition at line 55 of file pceof.h.

#define DEGTORAD   M_PI/180.0

Convert Degrees to Radian.

Definition at line 99 of file pceof.h.

Referenced by project_field_eof().

#define EARTH_RADIUS   6371229.0

Earth Radius.

Definition at line 97 of file pceof.h.

Referenced by project_field_eof().

#define FALSE   0

FALSE value macro is 0.

Definition at line 94 of file pceof.h.

#define TRUE   1

TRUE value macro is 1.

Definition at line 92 of file pceof.h.


Function Documentation

void normalize_pc ( double *  norm_all,
double *  first_variance,
double *  buf_renorm,
double *  bufin,
int  neof,
int  ntime 
)

Normalize a 2D variable by the norm of the first column of the first dimension and recompute the new norm.

Parameters:
[out] norm_all New norm vector
[in,out] first_variance Variance of the first column of the first dimension. Only calculate if not set to -9999.9999
[out] buf_renorm 2D field normalized
[in] bufin Input 2D field
[in] neof EOF dimension
[in] ntime Time dimension

Definition at line 60 of file normalize_pc.c.

Referenced by main(), and wt_downscaling().

00060                                                                                                                {
00061 
00071   int eof; /* EOF loop counter */
00072   int nt; /* Time loop counter */
00073 
00074   /* Check if we need to calculate the variance of the first column of the first dimension */
00075   if (*first_variance == -9999.9999) {
00076     eof = 0;
00077     *first_variance = gsl_stats_variance(&(bufin[eof*ntime]), 1, ntime);
00078     printf("first variance set=%lf %lf!\n",*first_variance,sqrt(*first_variance));
00079   }
00080   else
00081     printf("first variance=%lf %lf!\n",*first_variance,sqrt(*first_variance));
00082 
00083   /* Loop over all EOFs */
00084   for (eof=0; eof<neof; eof++) {
00085 
00086     //    for (nt=0; nt<ntime; nt++) {
00087     //      printf("norm_1 %d %d %lf\n",eof,nt,bufin[eof+nt*neof]);
00088     //    }
00089 
00090     /* Loop over time */
00091     for (nt=0; nt<ntime; nt++)
00092       /* Normalize with the first variance */
00093       buf_renorm[nt+eof*ntime] = bufin[nt+eof*ntime] / sqrt(*first_variance);
00094 
00095     /*    for (nt=(ntime-5); nt<ntime; nt++)
00096       printf("bufin %d eof %d %lf\n",nt,eof,bufin[nt+eof*ntime]);
00097     
00098     printf("before renorm %d %d %lf %lf ",eof,ntime,bufin[ntime-5+eof*ntime], sqrt(gsl_stats_variance(&(bufin[eof*ntime]), 1, ntime)));
00099     printf("renorm %lf\n",buf_renorm[ntime-5+eof*ntime]);*/
00100 
00101     /* Recompute the norm for each EOF */
00102     norm_all[eof] = gsl_stats_variance(&(buf_renorm[eof*ntime]), 1, ntime);
00103 
00104     printf("%s: Norm %d %lf\n",__FILE__,eof,sqrt(norm_all[eof]));
00105 
00106   }
00107 }

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.

Parameters:
[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 }


Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1