Changeset 1168


Ignore:
Timestamp:
06/29/09 17:01:17 (16 years ago)
Author:
Mathieu Morlighem
Message:

Brand new DataInterp with a nice linear interpolation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk/src/c/DataInterpx/DataInterpx.cpp

    r282 r1168  
    1111int findindices(int* pm,int* pn,double* x,int x_rows, double* y,int y_rows, double xgrid,double ygrid);
    1212
    13 int DataInterpx( Vec* pdata_mesh,double* x, int x_rows, double* y, int y_rows, double* data, int M, int N, double* x_mesh, double* y_mesh, int nods) {
     13int DataInterpx( Vec* pdata_mesh,double* x_in, int x_rows, double* y_in, int y_rows, double* data, int M, int N, double* x_mesh, double* y_mesh, int nods) {
    1414
    15         int i;
    16         int m,n;
    17         int data_mesh_m; //local number of rows for vector data_mesh.
    1815
    1916        /*output: */
    2017        Vec data_mesh=NULL;
    2118       
     19        /*Intermediary*/
     20        double* x=NULL;
     21        double* y=NULL;
     22        int i,m,n;
     23        int ind;
     24        double dis;
    2225        double x_grid,y_grid;
    2326        double xi,eta;
    2427        double G1,G2,G3,G4,data_value;
    25 
     28        double area_1,area_2,area_3;
     29        double area;
    2630
    2731        /*Some checks on arguments: */
    28         if ((M<=0) || (N<=0) || (nods<=0)){
     32        if ((M<=2) || (N<=2) || (nods<=0)){
    2933                throw ErrorException(__FUNCT__,"nothing to be done according to the dimensions of input matrices and vectors.");
    30         }
    31         if(M!=(y_rows-1)){
    32                 throw ErrorException(__FUNCT__,"y vector length should be 1 more than data number of rows.");
    33         }
    34         if(N!=(x_rows-1)){
    35                 throw ErrorException(__FUNCT__,"x vector length should be 1 more than data number of columns.");
    3634        }
    3735
     
    3937        data_mesh=NewVec(nods);
    4038
    41         /*Nearest interpolation method for now: */
     39        /*Find out what kind of coordinates (x_in,y_in) have been given is input*/
     40        if(N==(x_rows-1) && M==(y_rows-1)){
     41
     42                /*The coordinates given in input describe the contour of each pixel. Take the center of each pixel*/
     43                x=(double*)xmalloc(N*sizeof(double));
     44                y=(double*)xmalloc(M*sizeof(double));
     45                for (i=0;i<N;i++) x[i]=(x_in[i]+x_in[i+1])/2;
     46                for (i=0;i<M;i++) y[i]=(y_in[i]+y_in[i+1])/2;
     47                x_rows=x_rows-1;
     48                y_rows=y_rows-1;
     49        }
     50        else if (M==x_rows && N==x_rows){
     51
     52                /*The coordinates given in input describe the center each pixel. Keep them*/
     53                x=(double*)xmalloc(N*sizeof(double));
     54                y=(double*)xmalloc(M*sizeof(double));
     55                for (i=0;i<N;i++) x[i]=x_in[i];
     56                for (i=0;i<M;i++) y[i]=y_in[i];
     57        }
     58        else{
     59                throw ErrorException(__FUNCT__,"x and y vectors length should be 1 or 0 more than data number of rows.");
     60        }
     61
     62        /*Linear (triangle) interpolation: */
    4263        for ( i=MPI_Lowerrow(nods); i<MPI_Upperrow(nods); i++) {
    4364
     
    4869                if(findindices(&n,&m,x,x_rows, y,y_rows, x_grid,y_grid)){
    4970                       
    50                         /*Do a bilinear interpolation. First find parameter coordinates: */
    51                         xi=-1.0+2*(x_grid-x[n])/(x[n+1]-x[n]);
    52                         eta=-1.0+2*(y_grid-y[m])/(y[m+1]-y[m]);
    53                         /*Then find values of data at each grid: (xi,eta)=(0,0),(1,0),(1,1),(0,1) */
    54                         G1=*(data+m*N+n);
    55                         G2=*(data+m*N+n+1);
    56                         G3=*(data+(m+1)*N+n+1);
    57                         G4=*(data+(m+1)*N+n);
    58                         /*Find data_value, by bilinear interpolation: */
    59                         data_value=G1*(1+xi)*(1+eta)/4.0+ G2*(1-xi)*(1+eta)/4.0+G3*(1-xi)*(1-eta)/4.0+G4*(1+xi)*(1-eta)/4.0;
     71                        /*Get area*/
     72                        area=(x[n+1]-x[n])*(y[m+1]-y[m]);
    6073
     74                        /*is it the upper right triangle?*/
     75                        /*2'     3'
     76                         *+-----+
     77                         *1\    |
     78                         *| \   |
     79                         *|  \  |
     80                         *|   \ |
     81                         *|    \|
     82                         *2----3+1' */
     83                        if ((x_grid-x[n])/(x[n+1]-x[n])<(y_grid-y[m])/(y[m+1]-y[m])){
     84
     85                                /*Then find values of data at each summit*/
     86                                G1=*(data+m*N+n);
     87                                G2=*(data+(m+1)*N+n+1);
     88                                G3=*(data+(m+1)*N+n);
     89
     90                                /*Get first area coordinate*/
     91                                area_1=((y[m+1]-y_grid)*(x[n+1]-x[n]))/area;
     92                                /*Get second area coordinate*/
     93                                area_2=((x_grid-x[n])*(y[m+1]-y[m]))/area;
     94                                /*Get third area coordinate = 1-area1-area2*/
     95                                area_3=1-area_1-area_2;
     96
     97                                /*interpolate*/
     98                                data_value=area_1*G1+area_2*G2+area_3*G3;
     99                        }
     100                        else {
     101
     102                                /*Then find values of data at each summit*/
     103                                G1=*(data+(m+1)*N+n+1);
     104                                G2=*(data+m*N+n);
     105                                G3=*(data+m*N+n+1);
     106
     107                                /*Get first area coordinate*/
     108                                area_1=((y_grid-y[m])*(x[n+1]-x[n]))/area;
     109                                /*Get second area coordinate*/
     110                                area_2=((x[n+1]-x_grid)*(y[m+1]-y[m]))/area;
     111                                /*Get third area coordinate = 1-area1-area2*/
     112                                area_3=1-area_1-area_2;
     113
     114                                /*interpolate*/
     115                                data_value=area_1*G1+area_2*G2+area_3*G3;
     116                        }
     117
     118                        /*Treat NANs: take the closest non nan value avomg neighbors*/
     119                        if isnan(data_value){
     120                                ind=m*N+n;
     121                                dis=pow(x[n+1]-x[n],2);
     122                                if ( ((pow(y_grid-y[m],2)+pow(x_grid-x[n+1],2))<dis) && (!isnan(data[m*N+n+1]))){
     123                                        ind=m*N+n+1;
     124                                        dis=pow(y_grid-y[m],2)+pow(x_grid-x[n+1],2);
     125                                }
     126                                if ( ((pow(y_grid-y[m+1],2)+pow(x_grid-x[n],2))<dis) && (!isnan(data[(m+1)*N+n]))){
     127                                        ind=(m+1)*N+n;
     128                                        dis=pow(y_grid-y[m+1],2)+pow(x_grid-x[n],2);
     129                                }
     130                                if ( ((pow(y_grid-y[m+1],2)+pow(x_grid-x[n+1],2))<dis) && (!isnan(data[(m+1)*N+n+1]))){
     131                                        ind=(m+1)*N+n+1;
     132                                        dis=pow(y_grid-y[m+1],2)+pow(x_grid-x[n+1],2);
     133                                }
     134                                data_value=*(data+ind);
     135                        }
    61136                }
    62137                else{
Note: See TracChangeset for help on using the changeset viewer.