/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/utils/eh_grid.c

Go to the documentation of this file.
00001 #include <eh_utils.h>
00002 
00003 #if !defined( OLD_NDGRID )
00004 
00005 CLASS ( Eh_grid )
00006 {
00007    void **data;
00008    double *x;
00009    double *y;
00010    gssize low_x;
00011    gssize low_y;
00012    gssize n_x;
00013    gssize n_y;
00014    gssize el_size;
00015 };
00016 
00017 //DERIVED_CLASS( Eh_grid , Eh_dbl_grid );
00018 //DERIVED_CLASS( Eh_grid , Eh_int_grid );
00019 
00020 Eh_ind_2 eh_ind_2_create( int i , int j )
00021 {
00022    Eh_ind_2 ind;
00023    ind.i = i;
00024    ind.j = j;
00025    return ind;
00026 }
00027 
00028 gboolean eh_ind_2_cmp( Eh_ind_2 a , Eh_ind_2 b )
00029 {
00030    return a.i==b.i && a.j==b.j;
00031 }
00032 
00033 Eh_ind_2 *eh_ind_2_dup( Eh_ind_2 *src , Eh_ind_2 *dest )
00034 {
00035    if ( !dest )
00036       dest = eh_new( Eh_ind_2 , 1 );
00037    dest->i = src->i;
00038    dest->j = src->j;
00039    return dest;
00040 }
00041 
00042 gssize eh_grid_n_x( Eh_grid g )
00043 {
00044    return g->n_x;
00045 }
00046 
00047 gssize eh_grid_n_y( Eh_grid g )
00048 {
00049    return g->n_y;
00050 }
00051 
00052 gssize eh_grid_n_el( Eh_grid g )
00053 {
00054    return g->n_x*g->n_y;
00055 }
00056 
00057 gssize eh_grid_el_size( Eh_grid g )
00058 {
00059    return g->el_size;
00060 }
00061 
00062 gssize eh_grid_low_x( Eh_grid g )
00063 {
00064    return g->low_x;
00065 }
00066 
00067 gssize eh_grid_low_y( Eh_grid g )
00068 {
00069    return g->low_y;
00070 }
00071 
00072 double* eh_grid_x( Eh_grid g )
00073 {
00074    return g->x;
00075 }
00076 
00077 double* eh_grid_y( Eh_grid g )
00078 {
00079    return g->y;
00080 }
00081 
00082 void* eh_grid_row( Eh_grid g , gssize row )
00083 {
00084    return g->data[row];
00085 }
00086 
00087 void** eh_grid_data( Eh_grid g )
00088 {
00089    return g->data;
00090 }
00091  
00092 double**
00093 eh_dbl_grid_data( Eh_grid g )
00094 {
00095    return (double**)(g->data);
00096 }
00097 
00098 double**
00099 eh_dbl_grid_data_start( Eh_grid g )
00100 {
00101    return (double**)(eh_grid_data_start(g));
00102 }
00103 
00104 void* eh_grid_data_start( Eh_grid g )
00105 {
00106    return (gchar*)(g->data[g->low_x]) + g->low_y*g->el_size;
00107 }
00108 
00109 Eh_grid eh_grid_set_data( Eh_grid g , void** new_data )
00110 {
00111    g->data = new_data;
00112    return g;
00113 }
00114 
00115 Eh_grid eh_grid_set_x_lin( Eh_grid g , double x_0 , double dx )
00116 {
00117    eh_require( g );
00118 
00119    if ( g->x )
00120    {
00121       eh_dbl_array_linspace( g->x , g->n_x , x_0 , dx );
00122    }
00123    return g;
00124 }
00125 
00126 Eh_grid eh_grid_set_y_lin( Eh_grid g , double y_0 , double dy )
00127 {
00128    eh_require( g );
00129 
00130    if ( g->y )
00131    {
00132       eh_dbl_array_linspace( g->y , g->n_y , y_0 , dy );
00133    }
00134    return g;
00135 }
00136 
00137 Eh_grid eh_grid_malloc( gssize n_x , gssize n_y , gssize size )
00138 {
00139    Eh_grid g;
00140 
00141    NEW_OBJECT( Eh_grid , g );
00142    
00143    eh_return_val_if_fail( n_x>=0 , NULL );
00144    eh_return_val_if_fail( n_y>=0 , NULL );
00145    eh_return_val_if_fail( size>0 , NULL );
00146 
00147    g->data    = NULL;
00148    g->x       = NULL;
00149    g->y       = NULL;
00150    g->n_x     = 0;
00151    g->n_y     = 0;
00152    g->low_x   = 0;
00153    g->low_y   = 0;
00154    g->el_size = size;
00155 
00156    eh_grid_resize( g , n_x , n_y );
00157 
00158    return g;
00159 }
00160 
00161 Eh_dbl_grid
00162 eh_dbl_grid_new_set( gint n_x , gint n_y , double** d )
00163 {
00164    Eh_dbl_grid g;
00165 
00166    NEW_OBJECT( Eh_dbl_grid , g );
00167 
00168    eh_return_val_if_fail( n_x>=0  , NULL );
00169    eh_return_val_if_fail( n_y>=0  , NULL );
00170    eh_return_val_if_fail( d!=NULL , NULL );
00171 
00172    g->data    = (void**)d;
00173    g->x       = eh_new( double , n_x );
00174    g->y       = eh_new( double , n_y );
00175    g->n_x     = n_x;
00176    g->n_y     = n_y;
00177    g->low_x   = 0;
00178    g->low_y   = 0;
00179    g->el_size = sizeof(double);
00180 
00181    return g;
00182 }
00183 
00184 Eh_grid eh_grid_malloc_uniform( gssize n_x , gssize n_y , gssize size , double dx , double dy )
00185 {
00186    Eh_grid g = eh_grid_malloc( n_x , n_y , size );
00187 
00188    eh_grid_set_y_lin( g , 0 , dy );
00189    eh_grid_set_x_lin( g , 0 , dx );
00190 
00191    return g;
00192 }
00193 
00194 Eh_grid eh_grid_resize( Eh_grid g , gssize n_x , gssize n_y )
00195 {
00196    if ( g )
00197    {
00198       gssize i;
00199 
00200       if ( n_x==0 || n_y==0 )
00201       {
00202          if ( g->data )
00203             eh_free( g->data[0] );
00204          eh_free( g->data );
00205 
00206          g->data = NULL;
00207       }
00208       else
00209       {
00210          if ( g->data )
00211          {
00212             g->data    = eh_renew( void* , g->data , n_x );
00213 //            g->data[0] = eh_realloc( g->data[0] , n_x*n_y*g->el_size , __FILE__ , __LINE__ );
00214             g->data[0] = eh_renew( gchar , g->data[0] , n_x*n_y*g->el_size );
00215          }
00216          else
00217          {
00218             g->data    = eh_new( void* , n_x );
00219 //            g->data[0] = eh_malloc( n_x*n_y*g->el_size , NULL , __FILE__ , __LINE__ );
00220             g->data[0] = eh_new( gchar , n_x*n_y*g->el_size );
00221          }
00222          for ( i=1 ; i<n_x ; i++ )
00223             g->data[i] = (gint8*)(g->data[i-1]) + n_y*g->el_size;
00224       }
00225 
00226       if ( n_x==0 )
00227          eh_free( g->x );
00228       else
00229          g->x = eh_renew( double , g->x , n_x );
00230 
00231       if ( n_y==0 )
00232          eh_free( g->y );
00233       else
00234          g->y = eh_renew( double , g->y , n_y );
00235 
00236       g->n_x = n_x;
00237       g->n_y = n_y;
00238    }
00239    return g;
00240 }
00241 
00242 Eh_grid eh_grid_add_row( Eh_grid g , void* new_row )
00243 {
00244    eh_require( g );
00245    eh_grid_resize( g , g->n_x+1 , g->n_y );
00246    if ( new_row )
00247       g_memmove( g->data[g->n_x-1] , new_row , g->n_y*g->el_size );
00248    return g;
00249 }
00250 
00251 Eh_grid eh_grid_add_column( Eh_grid g , void* new_column )
00252 {
00253    eh_grid_resize( g , g->n_x , g->n_y+1 );
00254    if ( new_column )
00255    {
00256       gssize i;
00257       gssize offset = (g->n_y-1)*g->el_size;
00258       for ( i=0 ; i<g->n_x ; i++ )
00259          g_memmove( (gint8*)(g->data[i])+offset , new_column , g->el_size );
00260    }
00261    return g;
00262 }
00263 
00264 void eh_grid_free_data( Eh_grid g , gboolean free_data )
00265 {
00266    if ( g )
00267    {
00268       if ( free_data && g->data )
00269       {
00270          eh_grid_reindex( g , 0 , 0 );
00271          eh_free( g->data[0] );
00272       }
00273       eh_free( g->data    );
00274       eh_free( g->x       );
00275       eh_free( g->y       );
00276    }
00277 }
00278 
00279 Eh_grid eh_grid_destroy( Eh_grid g , gboolean free_data )
00280 {
00281    if ( g )
00282    {
00283       eh_grid_free_data( g , free_data );
00284       eh_free( g );
00285    }
00286    return NULL;
00287 }
00288 
00289 void eh_grid_dump( FILE *fp , Eh_grid g )
00290 {
00291    fwrite( &(g->n_x)     , sizeof(gssize) , 1             , fp );
00292    fwrite( &(g->n_y)     , sizeof(gssize) , 1             , fp );
00293    fwrite( &(g->el_size) , sizeof(gssize) , 1             , fp );
00294    fwrite( &(g->low_x)   , sizeof(gssize) , 1             , fp );
00295    fwrite( &(g->low_y)   , sizeof(gssize) , 1             , fp );
00296    fwrite( g->x          , sizeof(double) , g->n_x        , fp );
00297    fwrite( g->y          , sizeof(double) , g->n_y        , fp );
00298    fwrite( g->data[0]    , g->el_size     , g->n_x*g->n_y , fp );
00299 }
00300 
00301 Eh_grid eh_grid_load( FILE *fp )
00302 {
00303    gssize n_x, n_y, el_size;
00304    gssize low_x, low_y;
00305    Eh_grid g;
00306 
00307    fread( &n_x       , sizeof(gssize) , 1       , fp );
00308    fread( &n_y       , sizeof(gssize) , 1       , fp );
00309    fread( &el_size   , sizeof(gssize) , 1       , fp );
00310 
00311    g = eh_grid_malloc( n_x , n_y , el_size );
00312 
00313    fread( &low_x     , sizeof(gssize) , 1       , fp );
00314    fread( &low_y     , sizeof(gssize) , 1       , fp );
00315 
00316    fread( g->x       , el_size        , n_x     , fp );
00317    fread( g->y       , el_size        , n_y     , fp );
00318    fread( g->data[0] , el_size        , n_x*n_y , fp );
00319 
00320    eh_grid_reindex( g , low_x , low_y );
00321 
00322    return g;
00323 }
00324 
00325 gboolean eh_grid_cmp_data( Eh_grid g_1 , Eh_grid g_2 )
00326 {
00327    gboolean is_same = FALSE;
00328 
00329    if ( !eh_grid_is_same_size( g_1 , g_2 ) )
00330       is_same = FALSE;
00331    else
00332    {
00333       gssize n_bytes = g_1->n_x*g_1->n_y*g_1->el_size;
00334       is_same = (memcmp( g_1->data[0] , g_2->data[0] , n_bytes )==0)?TRUE:FALSE;
00335    }
00336 
00337    return is_same;
00338 }
00339 
00340 gboolean eh_grid_cmp_x_data( Eh_grid g_1 , Eh_grid g_2 )
00341 {
00342    gboolean is_same = FALSE;
00343 
00344    if ( g_1->n_x != g_2->n_x )
00345       is_same = FALSE;
00346    else
00347       is_same = (memcmp( g_1->x , g_2->x , g_1->n_x )==0)?TRUE:FALSE;
00348 
00349    return is_same;
00350 }
00351 
00352 gboolean eh_grid_cmp_y_data( Eh_grid g_1 , Eh_grid g_2 )
00353 {
00354    gboolean is_same = FALSE;
00355 
00356    if ( g_1->n_y != g_2->n_y )
00357       is_same = FALSE;
00358    else
00359       is_same = (memcmp( g_1->y , g_2->y , g_1->n_y )==0)?TRUE:FALSE;
00360 
00361    return is_same;
00362 }
00363 
00364 gboolean eh_grid_cmp( Eh_grid g_1 , Eh_grid g_2 )
00365 {
00366    gboolean is_same = FALSE;
00367 
00368    if ( !eh_grid_is_same_size( g_1 , g_2 ) )
00369       is_same = FALSE;
00370    else
00371    {
00372       is_same =    eh_grid_cmp_data( g_1 , g_2 )
00373                 && eh_grid_cmp_x_data( g_1 , g_2 )
00374                 && eh_grid_cmp_y_data( g_1 , g_2 );
00375    }
00376 
00377    return is_same;
00378 }
00379 
00380 gboolean eh_dbl_grid_cmp( Eh_dbl_grid g_1 , Eh_dbl_grid g_2 , double eps )
00381 {
00382    gboolean is_same;
00383 
00384    if ( !eh_grid_is_same_size( g_1 , g_2 ) )
00385       is_same = FALSE;
00386    else if ( eps<=0 )
00387       is_same = eh_grid_cmp( g_1 , g_2 );
00388    else
00389    {
00390       gssize i, n_elem = eh_grid_n_el(g_1);
00391       double* data_1 = eh_grid_data_start( g_1 );
00392       double* data_2 = eh_grid_data_start( g_2 );
00393       for ( i=0,is_same=TRUE ; i<n_elem && is_same ; i++ )
00394          if ( fabs( data_1[i] - data_2[i] ) > eps )
00395             is_same = FALSE;
00396    }
00397    return is_same;
00398 }
00399 
00400 Eh_grid
00401 eh_grid_dup( Eh_grid g )
00402 {
00403    Eh_grid new_grid = eh_grid_malloc( g->n_x , g->n_y , g->el_size );
00404    eh_grid_copy( new_grid , g );
00405 
00406    return new_grid;
00407 }
00408 
00409 Eh_grid eh_grid_copy( Eh_grid dest , Eh_grid src )
00410 {
00411    gssize low_x = src->low_x;
00412    gssize low_y = src->low_y;
00413 
00414    eh_require( src->n_x==dest->n_x         );
00415    eh_require( src->n_y==dest->n_y         );
00416    eh_require( src->el_size==dest->el_size );
00417 
00418    eh_grid_reindex( src , 0 , 0 );
00419 
00420    memcpy( dest->data[0] , src->data[0] , src->n_x*src->n_y*src->el_size );
00421    memcpy( dest->x       , src->x       , src->n_x*sizeof(double)        );
00422    memcpy( dest->y       , src->y       , src->n_y*sizeof(double)        );
00423 
00424    eh_grid_reindex( src  , low_x , low_y );
00425    eh_grid_reindex( dest , low_x , low_y );
00426 
00427    return dest;
00428 }
00429 
00430 Eh_grid eh_grid_copy_data( Eh_grid dest , Eh_grid src )
00431 {
00432    gssize low_x = src->low_x;
00433    gssize low_y = src->low_y;
00434 
00435    eh_require( src->n_x==dest->n_x         );
00436    eh_require( src->n_y==dest->n_y         );
00437    eh_require( src->el_size==dest->el_size );
00438 
00439    eh_grid_reindex( src , 0 , 0 );
00440 
00441    memcpy( dest->data[0] , src->data[0] , src->n_x*src->n_y*src->el_size );
00442 
00443    eh_grid_reindex( src  , low_x , low_y );
00444    eh_grid_reindex( dest , low_x , low_y );
00445 
00446    return dest;
00447 }
00448 
00449 Eh_grid
00450 eh_grid_reindex( Eh_grid g , gssize low_x , gssize low_y )
00451 {
00452    gssize i;
00453    gssize change_low_x = low_x - g->low_x;
00454    gssize change_low_y = low_y - g->low_y;
00455 
00456    if ( change_low_x == 0 && change_low_y == 0 )
00457       return g;
00458 
00459    for ( i=g->low_x ; i<g->n_x+g->low_x ; i++ )
00460       g->data[i] = (gint8*)(g->data[i]) - change_low_y*g->el_size;
00461    g->data -= change_low_x;
00462 
00463    g->x -= change_low_x;
00464    g->y -= change_low_y;
00465 
00466    g->low_x = low_x;
00467    g->low_y = low_y;
00468 
00469    return g;
00470 }
00471 
00472 gboolean eh_grid_is_in_domain( Eh_grid g , gssize i , gssize j )
00473 {
00474    return i>=g->low_x && j>=g->low_y && i<g->n_x+g->low_x && j<g->n_y+g->low_y;
00475 }
00476 
00477 gboolean eh_grid_is_same_size( Eh_grid g_1 , Eh_grid g_2 )
00478 {
00479    return    g_1->n_x     == g_2->n_x
00480           && g_1->n_y     == g_2->n_y
00481           && g_1->el_size == g_2->el_size;
00482 }
00483 
00484 Eh_grid_id eh_grid_sub_to_id( gssize n_j , gssize i , gssize j )
00485 {
00486    return i*n_j + j;
00487 }
00488 
00489 Eh_ind_2 eh_grid_id_to_sub( gssize n_i , Eh_grid_id id )
00490 {
00491    Eh_ind_2 sub;
00492 
00493    sub.i = id/n_i;
00494    sub.j = id%n_i;
00495 
00496    return sub;
00497 }
00498 
00499 void eh_dbl_grid_set_val( Eh_dbl_grid g , gssize i , gssize j , double val )
00500 {
00501    ((double*)(g->data[i]))[j] = val;
00502 }
00503 
00504 void eh_int_grid_set_val( Eh_dbl_grid g , gssize i , gssize j , int val )
00505 {
00506    ((int*)(g->data[i]))[j] = val;
00507 }
00508 
00509 double eh_dbl_grid_val( Eh_dbl_grid g , gssize i , gssize j )
00510 {
00511    return ((double*)(g->data[i]))[j];
00512 }
00513 
00514 int eh_int_grid_val( Eh_int_grid g , gssize i , gssize j )
00515 {
00516    return ((int*)(g->data[i]))[j];
00517 }
00518 
00519 void* eh_grid_loc( Eh_grid g , gssize i , gssize j )
00520 {
00521    return (gchar*)(g->data[i])+j*g->el_size;
00522 }
00523 
00524 int eh_dbl_grid_write( FILE *fp , Eh_dbl_grid g )
00525 {
00526    size_t s=0;
00527    int n_i     = g->n_x*g->n_y;
00528    int el_size = g->el_size;
00529    int n, i, i_0;
00530    int one = 1, size;
00531    double this_val;
00532    double* data = eh_grid_data_start(g);
00533 
00534    for ( i_0=0 ; i_0<n_i ; i_0+=n )
00535    {
00536 //      if ( i_0==n_i-1 || g->data[0][i_0] == g->data[0][i_0+1] )
00537       if ( i_0==n_i-1 || data[i_0] == data[i_0+1] )
00538       {
00539          this_val = data[i_0];
00540 
00541 //         for ( i=i_0,n=0 ; i<n_i && g->data[0][i]==this_val ; i++,n++ );
00542          for ( i=i_0,n=0 ; i<n_i && data[i]==this_val ; i++,n++ );
00543 
00544          s += fwrite( &el_size  , sizeof(int) , 1 , fp )*sizeof(int);
00545          s += fwrite( &n        , sizeof(int) , 1 , fp )*sizeof(int);
00546          s += fwrite( &this_val , el_size     , 1 , fp )*el_size;
00547       }
00548       else
00549       {
00550 //         for ( i=i_0+1,n=1 ; i<n_i && g->data[0][i-1]!=g->data[0][i] ; i++,n++ );
00551          for ( i=i_0+1,n=1 ; i<n_i && data[i-1]!=data[i] ; i++,n++ );
00552 
00553          if ( i<n_i )
00554             n--;
00555 
00556          size = n*el_size;
00557 
00558          s += fwrite( &size     , sizeof(int) , 1 , fp )*sizeof(int);
00559          s += fwrite( &one      , sizeof(int) , 1 , fp )*sizeof(int);
00560          s += fwrite( data+i_0  , size        , 1 , fp )*size;
00561 //         s += fwrite( &(g->data[0][i_0])  , size        , 1 , fp )*size;
00562       }
00563    }
00564 
00565    return s;
00566 }
00567 
00568 gboolean eh_grid_is_compatible( Eh_grid g_1 , Eh_grid g_2 )
00569 {
00570    gboolean ans=FALSE;
00571 
00572    if (    g_1
00573         && g_2
00574         && g_1->n_x     == g_2->n_x
00575         && g_1->n_y     == g_2->n_y 
00576         && g_1->el_size == g_2->el_size )
00577       ans = TRUE;
00578 
00579    return ans;
00580 }
00581 
00582 
00583 Eh_dbl_grid eh_dbl_grid_subtract( Eh_dbl_grid g_1 , Eh_dbl_grid g_2 )
00584 {
00585    gssize i;
00586    double* g_1_data = eh_grid_data_start(g_1);
00587    double* g_2_data = eh_grid_data_start(g_2);
00588    gssize n_i = g_1->n_x*g_1->n_y;
00589 
00590    eh_require( eh_grid_is_compatible( g_1 , g_2 ) );
00591 
00592    for ( i=0 ; i<n_i ; i++ )
00593       g_1_data[i] -= g_2_data[i];
00594 
00595    return g_1;
00596 }
00597 
00598 Eh_dbl_grid eh_dbl_grid_add( Eh_dbl_grid g_1 , Eh_dbl_grid g_2 )
00599 {
00600    gssize i;
00601    double* g_1_data = eh_grid_data_start(g_1);
00602    double* g_2_data = eh_grid_data_start(g_2);
00603    gssize n_i = g_1->n_x*g_1->n_y;
00604 
00605    eh_require( eh_grid_is_compatible( g_1 , g_2 ) );
00606 
00607    for ( i=0 ; i<n_i ; i++ )
00608       g_1_data[i] += g_2_data[i];
00609 
00610    return g_1;
00611 }
00612 
00613 double eh_dbl_grid_sum( Eh_dbl_grid g )
00614 {
00615    return eh_dbl_grid_sum_bad_val( g , eh_nan() );
00616 }
00617 
00618 double eh_dbl_grid_sum_bad_val( Eh_dbl_grid g , double bad_val )
00619 {
00620    double sum=0;
00621 
00622    eh_require( g )
00623    {
00624       gssize i;
00625       gssize n_i   = eh_grid_n_el(g);
00626       double* data = eh_grid_data_start( g );
00627 
00628       if ( eh_isnan( bad_val ) )
00629       {
00630          for ( i=0 ; i<n_i ; i++ )
00631             if ( !eh_isnan( data[i] ) )
00632                sum += data[i];
00633       }
00634       else
00635          for ( i=0 ; i<n_i ; i++ )
00636             if ( fabs( data[i] - bad_val )>1e-12 )
00637                sum += data[i];
00638    }
00639 
00640    return sum;
00641 }
00642 
00643 Eh_dbl_grid eh_dbl_grid_set( Eh_dbl_grid g , double val )
00644 {
00645    gssize n_i = eh_grid_n_el( g );
00646    gssize i;
00647    double* data = eh_grid_data_start( g );
00648    for ( i=0 ; i<n_i ; i++ )
00649       data[i] = val;
00650    return g;
00651 }
00652 
00653 Eh_dbl_grid eh_dbl_grid_randomize( Eh_dbl_grid g )
00654 {
00655    gssize n_i = eh_grid_n_el( g );
00656    gssize i;
00657    double* data = eh_grid_data_start( g );
00658    for ( i=0 ; i<n_i ; i++ )
00659       data[i] = g_random_double();
00660    return g;
00661 }
00662 
00663 void eh_dbl_grid_scalar_mult( Eh_dbl_grid g , double scalar )
00664 {
00665    eh_return_if_fail( g )
00666    {
00667       gssize i;
00668       gssize n_i = g->n_x*g->n_y;
00669       double* data = eh_grid_data_start(g);
00670       for ( i=0 ; i<n_i ; i++ )
00671          data[i] *= scalar;
00672    }
00673 }
00674 
00675 Eh_dbl_grid
00676 eh_dbl_grid_rotate( Eh_dbl_grid g , double angle , gssize i_0 , gssize j_0 , double* lost )
00677 {
00678    if ( g && !eh_compare_dbl(angle,0.,1e-12) )
00679    {
00680       double mass_error = 0;
00681       gssize i, j;
00682       gssize i_rotate, j_rotate;
00683       double r, alpha, new_angle;
00684       double d_i, d_j;
00685       gssize high_x    = g->n_x+g->low_x;
00686       gssize high_y    = g->n_y+g->low_y;
00687       double** data, **temp_data;
00688       Eh_dbl_grid temp = eh_grid_new( double , g->n_x , g->n_y );
00689 
00690       eh_grid_reindex( temp , g->low_x , g->low_y );
00691 
00692       temp_data = (double**)(temp->data);
00693       data      = (double**)(g->data);
00694 
00695       for ( i=g->low_x ; i<high_x ; i++ )
00696          for ( j=g->low_y ; j<high_y ; j++ )
00697          {
00698             if ( fabs(data[i][j]) > 1e-12 )
00699             {
00700                d_i       = i-i_0;
00701                d_j       = j-j_0;
00702 
00703                r         = sqrt( pow(d_i,2.) + pow(d_j,2.) );
00704                alpha     = atan2( d_j , d_i );
00705                new_angle = alpha + angle;
00706 
00707                i_rotate = eh_round( r*cos( new_angle ) , 1 )+i_0;
00708                j_rotate = eh_round( r*sin( new_angle ) , 1 )+j_0;
00709 
00710                if ( eh_grid_is_in_domain( temp , i_rotate , j_rotate ) )
00711                   temp_data[i_rotate][j_rotate] += data[i][j];
00712 //                  temp->data[i_rotate][j_rotate] = g->data[i][j];
00713                else
00714                   mass_error += data[i][j];
00715             }
00716          }
00717 
00718       if ( lost )
00719          *lost = mass_error;
00720 
00721       eh_grid_copy_data( g , temp );
00722       eh_grid_destroy( temp , TRUE );
00723    }
00724    else
00725    {
00726       if ( lost )
00727          *lost = 0.;
00728    }
00729 
00730    return g;
00731 }
00732 
00733 Eh_dbl_grid eh_dbl_grid_reduce( Eh_dbl_grid g ,
00734                                 gssize new_n_x , gssize new_n_y )
00735 {
00736    eh_require( new_n_x<=g->n_x );
00737    eh_require( new_n_y<=g->n_y );
00738 
00739    return eh_dbl_grid_remesh( g , new_n_x , new_n_y );
00740 }
00741 
00742 Eh_dbl_grid eh_dbl_grid_expand( Eh_dbl_grid g ,
00743                                 gssize new_n_x , gssize new_n_y )
00744 {
00745    eh_require( new_n_x>=g->n_x );
00746    eh_require( new_n_y>=g->n_y );
00747 
00748    return eh_dbl_grid_remesh( g , new_n_x , new_n_y );
00749 }
00750 
00751 Eh_dbl_grid eh_dbl_grid_remesh( Eh_dbl_grid g ,
00752                                 gssize new_n_x , gssize new_n_y )
00753 {
00754    gssize i, j;
00755    gssize cur_n_x, cur_n_y;
00756    Eh_dbl_grid new_grid;
00757    double *x_ind, *new_x_ind;
00758    double *y_ind, *new_y_ind;
00759    double *orig_x, *orig_y;
00760    double dx, dy;
00761 
00762    eh_require( g );
00763 
00764    if ( new_n_x == g->n_x && new_n_y == g->n_y )
00765       return eh_grid_dup( g );
00766 /*
00767    eh_require( g->n_x>=2   );
00768    eh_require( g->n_y>=2   );
00769    eh_require( new_n_x > 1 );
00770    eh_require( new_n_y > 1 );
00771 */
00772    cur_n_x = g->n_x;
00773    cur_n_y = g->n_y;
00774 
00775    if ( new_n_x == cur_n_x && new_n_y == cur_n_y )
00776       return eh_grid_dup( g );
00777 
00778    new_grid = eh_grid_new( double , new_n_x , new_n_y );
00779    eh_grid_reindex( new_grid , g->low_x , g->low_y );
00780 
00781    if ( cur_n_x==1 && new_n_x==1 )
00782       dx = 1;
00783    else
00784       dx = (cur_n_x-1.) / (double)(new_n_x-1.);
00785    if ( cur_n_y==1 && new_n_y==1 )
00786       dy = 1;
00787    else
00788       dy = (cur_n_y-1.) / (double)(new_n_y-1.);
00789 
00790    x_ind     = eh_new( double , g->n_x        );
00791    new_x_ind = eh_new( double , new_grid->n_x );
00792    y_ind     = eh_new( double , g->n_y        );
00793    new_y_ind = eh_new( double , new_grid->n_y );
00794 
00795    for ( i=0 ; i<g->n_x        ; i++ ) x_ind[i]     = i+g->low_x;
00796    for ( j=0 ; j<g->n_y        ; j++ ) y_ind[j]     = j+g->low_y;
00797 
00798    for ( i=0 ; i<new_grid->n_x ; i++ ) new_x_ind[i] = i*dx+new_grid->low_x;
00799    for ( j=0 ; j<new_grid->n_y ; j++ ) new_y_ind[j] = j*dy+new_grid->low_y;
00800 
00801    if ( new_x_ind[new_grid->n_x-1] > x_ind[g->n_x-1] )
00802       new_x_ind[new_grid->n_x-1] = (1.-1e-6)*x_ind[g->n_x-1];
00803    if ( new_y_ind[new_grid->n_y-1] > y_ind[g->n_y-1] )
00804       new_y_ind[new_grid->n_y-1] = (1.-1e-6)*y_ind[g->n_y-1];
00805 
00806    interpolate( x_ind         , x_ind       , g->n_x ,
00807                 new_x_ind     , new_grid->x , new_grid->n_x );
00808    interpolate( y_ind         , y_ind       , g->n_y ,
00809                 new_y_ind     , new_grid->y , new_grid->n_y );
00810 
00811    orig_x = g->x;
00812    orig_y = g->y;
00813 
00814    g->x = x_ind;
00815    g->y = y_ind;
00816 
00817    interpolate_2( g , new_grid );
00818 
00819    g->x = orig_x;
00820    g->y = orig_y;
00821 
00822    eh_free( x_ind     );
00823    eh_free( y_ind     );
00824    eh_free( new_x_ind );
00825    eh_free( new_y_ind );
00826 
00827    return new_grid;
00828 }
00829 
00830 void
00831 interpolate_2( Eh_dbl_grid source , Eh_dbl_grid dest )
00832 {
00833    interpolate_2_bad_val( source , dest , eh_nan() );
00834 }
00835 
00836 void
00837 interpolate_2_bad_val( Eh_dbl_grid source , Eh_dbl_grid dest ,
00838                        double bad_val )
00839 {
00840    gssize i,j;
00841    Eh_dbl_grid temp;
00842    double *temp_source, *temp_dest;
00843    gssize src_low_x=eh_grid_low_x(source), dest_low_x=eh_grid_low_x(dest);
00844    gssize src_low_y=eh_grid_low_y(source), dest_low_y=eh_grid_low_y(dest);
00845 
00846    eh_grid_reindex( source , 0 , 0 );
00847    eh_grid_reindex( dest   , 0 , 0 );
00848 
00849    temp        = eh_grid_new( double , eh_grid_n_x(source) , eh_grid_n_y(dest) );
00850    temp_source = eh_new( double , eh_grid_n_x(source) );
00851    temp_dest   = eh_new( double , eh_grid_n_x(dest)   );
00852 
00853    for ( i=0 ; i<eh_grid_n_x(source) ; i++ )
00854       interpolate_bad_val( eh_grid_y(source) , eh_grid_row(source,i) , eh_grid_n_y(source) ,
00855                            eh_grid_y(dest)   , eh_grid_row(temp,i)   , eh_grid_n_y(dest)   ,
00856                            bad_val );
00857 
00858    for ( j=0 ; j<eh_grid_n_y(dest) ; j++ )
00859    {
00860       for ( i=0 ; i<eh_grid_n_x(source) ; i++ )
00861          temp_source[i] = eh_dbl_grid_val(temp,i,j);
00862 
00863       interpolate_bad_val( eh_grid_x(source) , temp_source , eh_grid_n_x(source) ,
00864                            eh_grid_x(dest)   , temp_dest   , eh_grid_n_x(dest)   ,
00865                            bad_val );
00866 
00867       for ( i=0 ; i<eh_grid_n_x(dest) ; i++ )
00868          eh_dbl_grid_set_val( dest , i , j , temp_dest[i] );
00869 //         dest->data[i][j] = temp_dest[i];
00870    }
00871 
00872    eh_free( temp_dest   );
00873    eh_free( temp_source );
00874    eh_grid_destroy( temp , TRUE );
00875 
00876    eh_grid_reindex( source , src_low_x  , src_low_y  );
00877    eh_grid_reindex( dest   , dest_low_x , dest_low_y );
00878 
00879    return;
00880 }
00881 
00882 gboolean eh_grid_path_is_same( gssize* p_1 , gssize* p_2 )
00883 {
00884    gboolean is_same = TRUE;
00885 
00886    if ( p_1 != p_2 )
00887    {
00888       gssize len_1, len_2;
00889 
00890       eh_return_val_if_fail( p_1 , FALSE );
00891       eh_return_val_if_fail( p_2 , FALSE );
00892 
00893       len_1 = eh_grid_path_len( p_1 );
00894       len_2 = eh_grid_path_len( p_2 );
00895 
00896       if ( len_1==len_2 )
00897          is_same = (memcmp( p_1 , p_2 , sizeof(gssize)*len_1 )==0)?TRUE:FALSE;
00898       else
00899          is_same = FALSE;
00900    }
00901 
00902    return is_same;
00903 }
00904 
00905 gssize eh_grid_path_len( gssize* p )
00906 {
00907    gssize len = 0;
00908 
00909    eh_return_val_if_fail( p , 0 );
00910 
00911    for ( len=0 ; p[len]>=0 ; len++ );
00912 
00913    return len;
00914 }
00915 
00916 Eh_grid_id* eh_dbl_grid_line_ids( Eh_dbl_grid g , gssize i_0 , gssize j_0 , gssize i_1 , gssize j_1 )
00917 {
00918    gssize* path = NULL;
00919 
00920    if ( !(i_0==i_1 && j_0==j_1) )
00921    {
00922       gssize di = i_1-i_0;
00923       gssize dj = j_1-j_0;
00924 
00925       if ( di>0 && dj>0 )
00926       {
00927          gssize i;
00928          double to_corner;
00929          double x, y;
00930          double m        = dj / (double)di;
00931          gssize start_id = eh_grid_sub_to_id( eh_grid_n_y(g) , i_0 , j_0 );
00932          gssize end_id   = eh_grid_sub_to_id( eh_grid_n_y(g) , i_1 , j_1 );
00933          gssize max_len  = di + dj + 1;
00934 
00935          path = eh_new( gssize , max_len+1 );
00936 
00937          path[0] = start_id;
00938          x = i_0+.5;
00939          y = j_0+.5;
00940 
00941          for ( i=1 ; i<max_len && path[i-1]!=end_id ; i++ )
00942          {
00943             to_corner = (1.-(x-floor(x)) ) / ( 1.-(y-floor(y)) );
00944             if ( to_corner<m )
00945             {
00946                path[i] = path[i-1] + 1;
00947                x = floor(x+1);
00948             }
00949             else if ( to_corner>m )
00950             {
00951                path[i] = path[i-1] + eh_grid_n_y(g);
00952                y = floor(y+1);
00953             }
00954             else
00955             {
00956                path[i] = path[i-1] + eh_grid_n_y(g) + 1;
00957                x = floor(x+1);
00958                y = floor(y+1);
00959             }
00960          }
00961 
00962          path[i] = -1;
00963 
00964       }
00965       else if ( di<0 )
00966       {
00967          if ( dj<0 )
00968             path = eh_dbl_grid_line_ids( g , i_1 , j_1 , i_0 , j_0  );
00969          else
00970             path = eh_dbl_grid_line_ids( g , i_0 , j_0 , i_0-di , j_0  );
00971       }
00972       else
00973          path = eh_dbl_grid_line_ids( g , i_0 , j_0 , i_1 , j_0-dj  );
00974    }
00975 
00976    return path;
00977 }
00978 /*
00979 gssize* eh_grid_id_transpose( gssize* id , gssize n_x , gssize n_y )
00980 {
00981    eh_require( n_x>0 );
00982    eh_require( n_y>0 );
00983 
00984    eh_return_val_if_fail( id , NULL );
00985 
00986    {
00987       gssize i;
00988       for ( i=0 ; id[i]>=0 ; i++ )
00989       {
00990          id[i] = mod(id[i],n_y)*n_x + floor(id[i],n_y);
00991       }
00992    }
00993 
00994    return id;
00995 }
00996 
00997 gssize* eh_grid_id_add( gssize* id , )
00998 */
00999 
01000 Eh_grid sed_grid_sub( Eh_grid g , int i_0 , int j_0 , int n_x , int n_y )
01001 {
01002    gssize i;
01003    Eh_grid sub;
01004 
01005    if ( i_0+n_x > g->n_x )
01006       n_x = g->n_x-i_0;
01007    if ( j_0+n_y > g->n_y )
01008       n_y = g->n_y-j_0;
01009 
01010    sub = eh_grid_malloc( n_x , n_y , g->el_size );
01011 
01012    for ( i=0 ; i<sub->n_x ; i++ )
01013       memcpy( sub->data[i] ,
01014               (gchar*)(g->data[i_0+i])+j_0*g->el_size ,
01015               sub->n_y*g->el_size );
01016    memcpy( sub->x , g->x+i_0 , sub->n_x*sizeof(double) );
01017    memcpy( sub->y , g->y+j_0 , sub->n_y*sizeof(double) );
01018 
01019 /*
01020    for ( i=0 ; i<sub->n_x ; i++ )
01021       sub->data[i] = (gint8*)(g->data[i_0])   + j_0*g->el_size;
01022 
01023    sub->n_x = n_x;
01024    sub->n_y = n_y;
01025    sub->low_x = 0;
01026    sub->low_y = 0;
01027 
01028    sub->data = eh_new( void* , sub->n_x );
01029 
01030    for ( i=0 ; i<sub->n_x ; i++ )
01031       sub->data[i] = (gint8*)(g->data[i_0])   + j_0*g->el_size;
01032 //      sub->data[i] = (gint8*)(g->data[i_0+1]) + j_0*g->el_size;
01033 
01034    if ( g->x )
01035       sub->x = g->x+i_0;
01036    else
01037       sub->x = NULL;
01038 
01039    if ( g->y )
01040       sub->y = g->y+j_0;
01041    else
01042       sub->y = NULL;
01043 */
01044 
01045    return sub;
01046 }
01047 /*
01048 void
01049 eh_dbl_grid_rebin( Eh_dbl_grid source , gint id_ul , gint id_lr , double dx , double dy )
01050 {
01051    gssize i,j;
01052    double **temp, *temp_source, *temp_dest;
01053    gssize src_low_x=source->low_x, dest_low_x=dest->low_x;
01054    gssize src_low_y=source->low_y, dest_low_y=dest->low_y;
01055    double** dest_data = (double**)(dest->data);
01056 
01057    eh_grid_reindex( source , 0 , 0 );
01058    eh_grid_reindex( dest   , 0 , 0 );
01059 
01060    temp    = eh_new( double* , source->n_x );
01061    temp[0] = eh_new( double  , source->n_x*dest->n_y );
01062    for ( i=1 ; i<source->n_x ; i++ )
01063       temp[i] = temp[i-1] + dest->n_y;
01064    temp_source = eh_new( double , source->n_x );
01065    temp_dest   = eh_new( double , dest->n_x   );
01066 
01067    dest_n_x = eh_dbl_array_rebin_len( src_n_x , dx );
01068    dest_n_y = eh_dbl_array_rebin_len( src_n_y , dy );
01069 
01070    dest = eh_grid_new( double , dest_n_x , dest_n_y );
01071 
01072    for ( i=0 ; i<n_x ; i++ )
01073    {
01074       eh_dbl_array_rebin( dest->data[i] , source->data[i]+j_0 , n_y , dy , &temp_len );
01075       if ( temp_len != dest_n_y )
01076          eh_require_not_reached();
01077    }
01078 
01079    for ( j=0 ; j<dest_n_y ; j++ )
01080    {
01081       eh_dbl_col_to_array( temp_source , temp[0]+j , dest_n_x , dest_n_y );
01082 
01083       temp_dest = eh_dbl_array_rebin( temp_source , n_x , dx , &temp_len );
01084 
01085       if ( temp_len != dest_n_x )
01086          eh_require_not_reached();
01087 
01088       eh_dbl_array_to_col( dest_data[0]+j , temp_dest , dest_n_x , dest_n_y );
01089 
01090       for ( i=0 ; i<dest_n_x ; i++ )
01091          dest_data[i][j] = temp_dest[i];
01092    }
01093 
01094    eh_free( temp_dest   );
01095    eh_free( temp_source );
01096    eh_free( temp[0]     );
01097    eh_free( temp        );
01098 
01099    eh_grid_reindex( source , src_low_x  , src_low_y  );
01100    eh_grid_reindex( dest   , dest_low_x , dest_low_y );
01101 
01102    return;
01103 }
01104 */
01105 
01106 void eh_dbl_grid_rebin( Eh_dbl_grid source , Eh_dbl_grid dest )
01107 {
01108    eh_dbl_grid_rebin_bad_val( source , dest , eh_nan() );
01109 }
01110 
01111 void eh_dbl_grid_rebin_bad_val( Eh_dbl_grid source , Eh_dbl_grid dest , double bad_val )
01112 {
01113    gssize i,j;
01114    double **temp, *temp_source, *temp_dest;
01115    gssize src_low_x=source->low_x, dest_low_x=dest->low_x;
01116    gssize src_low_y=source->low_y, dest_low_y=dest->low_y;
01117    double** dest_data = (double**)(dest->data);
01118 
01119    eh_grid_reindex( source , 0 , 0 );
01120    eh_grid_reindex( dest   , 0 , 0 );
01121 
01122    temp    = eh_new( double* , source->n_x );
01123    temp[0] = eh_new( double  , source->n_x*dest->n_y );
01124    for ( i=1 ; i<source->n_x ; i++ )
01125       temp[i] = temp[i-1] + dest->n_y;
01126    temp_source = eh_new( double , source->n_x );
01127    temp_dest   = eh_new( double , dest->n_x   );
01128 
01129    for ( i=0 ; i<source->n_x ; i++ )
01130       eh_rebin_dbl_array_bad_val( source->y , source->data[i] , source->n_y ,
01131                                   dest->y   , temp[i]         , dest->n_y   ,
01132                                   bad_val );
01133 
01134 //   dest_data = dest->data;
01135 
01136    for ( j=0 ; j<dest->n_y ; j++ )
01137    {
01138       for ( i=0 ; i<source->n_x ; i++ )
01139          temp_source[i] = temp[i][j];
01140 
01141       eh_rebin_dbl_array_bad_val( source->x , temp_source , source->n_x ,
01142                                   dest->x   , temp_dest   , dest->n_x   ,
01143                                   bad_val );
01144 
01145       for ( i=0 ; i<dest->n_x ; i++ )
01146          dest_data[i][j] = temp_dest[i];
01147    }
01148 
01149    eh_free( temp_dest   );
01150    eh_free( temp_source );
01151    eh_free( temp[0]     );
01152    eh_free( temp        );
01153 
01154    eh_grid_reindex( source , src_low_x  , src_low_y  );
01155    eh_grid_reindex( dest   , dest_low_x , dest_low_y );
01156 
01157    return;
01158 }
01159 
01160 void eh_grid_foreach( Eh_grid g , GFunc func , gpointer user_data )
01161 {
01162    eh_return_if_fail( g && func )
01163    {
01164       gssize i;
01165       gssize n_i = g->n_x*g->n_y;
01166 
01167       for ( i=0 ; i<n_i ; i++ )
01168          (*func)( (gchar*)(g->data[0])+i , user_data );
01169    }
01170 }
01171 
01172 Eh_dbl_grid eh_dbl_grid_populate( Eh_dbl_grid g  ,
01173                                   Populate_func f ,
01174                                   gpointer user_data )
01175 {
01176    gssize n;
01177    gssize population_size=100000;
01178    gssize low_x  = g->low_x;
01179    gssize low_y  = g->low_y;
01180    gssize high_x = g->low_x+g->n_x;
01181    gssize high_y = g->low_y+g->n_y;
01182    gssize i, j;
01183    double inc, x, y;
01184 
01185    for ( n=0 ; n<population_size ; n++ )
01186    {
01187       x = eh_get_fuzzy_dbl( low_x , high_x );
01188       y = eh_get_fuzzy_dbl( low_y , high_y );
01189       if ( (*f)( x , y , user_data ) )
01190       {
01191          i   = floor(x);
01192          j   = floor(y);
01193          inc = eh_dbl_grid_val(g,i,j) + 1;
01194          eh_dbl_grid_set_val( g , i , j , inc );
01195       }
01196    }
01197 
01198    eh_dbl_grid_scalar_mult( g , ((double)(g->n_x*g->n_y))/population_size );
01199 
01200    return g;
01201 }
01202 
01203 void eh_dbl_grid_fprintf( FILE* fp , const gchar* format , Eh_dbl_grid g )
01204 {
01205    eh_require( g      );
01206    eh_require( fp     );
01207    eh_require( format );
01208 
01209    if ( g && fp && format )
01210    {
01211       gssize i, j;
01212       for ( i=0 ; i<g->n_x ; i++ )
01213       {
01214          for ( j=0 ; j<g->n_y ; j++ )
01215             fprintf( fp , format , ((double*)(g->data[i]))[j] );
01216          fprintf( fp , "\n" );
01217       }
01218    }
01219 }
01220 
01221 #include <string.h> // included for g_memmove
01222 
01223 Eh_grid eh_grid_transpose( Eh_grid g )
01224 { 
01225    gssize low_x = g->low_x;
01226    gssize low_y = g->low_y;
01227 
01228    eh_grid_reindex( g , 0 , 0 );
01229 
01230    eh_debug( "Swap x and y" );
01231    {
01232       double* temp = eh_grid_x(g);
01233       g->x = g->y;
01234       g->y = temp;
01235    }
01236 
01237    eh_debug( "Swap x and y" );
01238    {
01239       gssize i, j;
01240 
01241       if ( g->n_x == g->n_y )
01242       {
01243          for ( i=0 ; i<g->n_x ; i++ )
01244             for ( j=i+1 ; j<g->n_y ; j++ )
01245                eh_memswap( (gint8*)(g->data[i])+j*g->el_size ,
01246                            (gint8*)(g->data[j])+i*g->el_size ,
01247                            g->el_size );
01248       }
01249       else
01250       {
01251          void** temp = eh_new( void* , g->n_y );
01252 
01253 //         temp[0] = eh_malloc( g->n_y*g->n_x*g->el_size , NULL , __FILE__ , __LINE__ );
01254          temp[0] = eh_new( gchar , g->n_y*g->n_x*g->el_size );
01255          for ( i=1 ; i<g->n_y ; i++ )
01256             temp[i] = (gint8*)(temp[i-1]) + g->n_x*g->el_size;
01257 
01258          for ( i=0 ; i<g->n_x ; i++ )
01259             for ( j=0 ; j<g->n_y ; j++ )
01260                g_memmove( (gint8*)(temp[j])+i*g->el_size    ,
01261                           (gint8*)(g->data[i])+j*g->el_size ,
01262                           g->el_size);
01263 
01264          g->data = eh_renew( void* , g->data , g->n_y );
01265          for ( i=1 ; i<g->n_y ; i++ )
01266             g->data[i] = (gint8*)(g->data[i-1]) + g->n_x*g->el_size;
01267 
01268          g_memmove( g->data[0] , temp[0] , g->n_x*g->n_y*g->el_size );
01269 
01270          eh_free( temp[0] );
01271          eh_free( temp );
01272       }
01273 
01274    }
01275 
01276    eh_debug( "Swap dimension lengths" );
01277    {
01278       gssize temp = g->n_x;
01279       g->n_x = g->n_y;
01280       g->n_y = temp;
01281    }
01282 
01283    eh_grid_reindex( g , low_y , low_x );
01284 
01285    return g;
01286 }
01287 /*
01288 Eh_dbl_grid eh_dbl_grid_dx( Eh_dbl_grid g )
01289 {
01290    double c = .25/h;
01291    for ( i=0 ; i<g->n_x ; i++ )
01292       for ( j=0 ; j<g->n_y ; j++ )
01293          dx->data[i][j] = c*(   g->data[i+1][j+1]
01294                               - g->data[i-1][j+1]
01295                               + g->data[i+1][j-1]
01296                               - g->data[i-1][j-1] ); 
01297 }
01298 
01299 Eh_dbl_grid eh_dbl_grid_dxx( Eh_dbl_grid g )
01300 {
01301    double c = 1./( 3*h*h );
01302    for ( i=0 ; i<g->n_x ; i++ )
01303       for ( j=0 ; j<g->n_y ; j++ )
01304          dx->data[i][j] = c*(     g->data[i+1][j+1]
01305                               - 2*g->data[i  ][j+1]
01306                               +   g->data[i-1][j+1]
01307                               +   g->data[i+1][j  ]
01308                               - 2*g->data[i  ][j  ]
01309                               +   g->data[i-1][j  ]
01310                               +   g->data[i+1][j-1]
01311                               - 2*g->data[i  ][j-1]
01312                               +   g->data[i-1][j-1] );
01313 }
01314 */
01315 Eh_dbl_grid eh_dbl_grid_diff( Eh_dbl_grid g , gssize n , gssize dim )
01316 {
01317    Eh_dbl_grid diff = eh_grid_new( double , g->n_x , g->n_y );
01318 
01319    if ( dim==1 )
01320    {
01321       eh_grid_transpose( g );
01322       diff = eh_grid_new( double , g->n_y , g->n_x );
01323    }
01324    else
01325       diff = eh_grid_new( double , g->n_x , g->n_y );
01326 
01327    {
01328       gssize i;
01329 
01330       for ( i=0 ; i<g->n_x ; i++ )
01331          eh_dbl_array_diff( diff->data[i] , g->data[i] , n , g->n_y );
01332    }
01333 
01334    if ( dim==1 )
01335    {
01336       eh_grid_transpose( diff );
01337       eh_grid_transpose( g );
01338    }
01339 
01340    return diff;
01341 }
01342 
01343 #endif
01344 

Generated on Fri Jan 4 18:04:16 2008 for sedflux by  doxygen 1.5.2