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
00018
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
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
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
00537 if ( i_0==n_i-1 || data[i_0] == data[i_0+1] )
00538 {
00539 this_val = data[i_0];
00540
00541
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
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
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
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
00768
00769
00770
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
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
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
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
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045 return sub;
01046 }
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
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
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>
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
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
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
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