00001 #include <eh_utils.h>
00002
00003 #if !defined( OLD_NDGRID )
00004
00005 CLASS( Eh_ndgrid )
00006 {
00007 double *data;
00008 gssize n_dim;
00009 gssize *size;
00010 gssize *low;
00011 double **x;
00012 gssize el_size;
00013 };
00014
00015 double* eh_ndgrid_x( Eh_ndgrid g , gssize dim )
00016 {
00017 eh_require( dim<g->n_dim );
00018 return g->x[dim];
00019 }
00020
00021 gssize eh_ndgrid_n( Eh_ndgrid g , gssize dim )
00022 {
00023 eh_require( dim<g->n_dim );
00024 return g->size[dim];
00025 }
00026
00027 Eh_ndgrid eh_ndgrid_malloc( gssize n_dim , gssize el_size , ... )
00028 {
00029 gssize n;
00030 gssize n_el=1;
00031 Eh_ndgrid g;
00032 va_list args;
00033
00034 NEW_OBJECT( Eh_ndgrid , g );
00035
00036 g->size = eh_new( gssize , n_dim );
00037 g->low = eh_new( gssize , n_dim );
00038 g->x = eh_new( double* , n_dim );
00039
00040 g->n_dim = n_dim;
00041
00042 va_start( args , el_size );
00043 for ( n=0 ; n<n_dim ; n++ )
00044 {
00045 g->size[n] = va_arg( args , gssize );
00046 g->low[n] = 0;
00047 g->x[n] = eh_new( double , g->size[n] );
00048 n_el *= g->size[n];
00049 }
00050 va_end( args );
00051
00052
00053
00054 g->data = (double*)eh_new( gchar , n_el*el_size );
00055
00056 return g;
00057 }
00058
00059 void eh_free_ndgrid_data( Eh_ndgrid g )
00060 {
00061 gssize n;
00062 if ( g )
00063 {
00064 for ( n=0 ; n<g->n_dim ; n++ )
00065 eh_free( g->x[n] );
00066 eh_free( g->x );
00067 eh_free( g->low );
00068 eh_free( g->size );
00069 eh_free( g->data );
00070 }
00071 }
00072
00073 double eh_ndgrid_ind( Eh_ndgrid g , ... )
00074 {
00075 gssize n;
00076 gssize id;
00077 gssize *sub;
00078 va_list args;
00079
00080 sub = eh_new( gssize , g->n_dim );
00081
00082 va_start( args , g );
00083 for ( n=0 ; n<g->n_dim ; n++ )
00084 sub[n] = va_arg( args , gssize );
00085 va_end( args );
00086
00087 id = eh_ndgrid_sub_to_id( g->size , sub , g->n_dim );
00088
00089 eh_free( sub );
00090
00091 return g->data[id];
00092 }
00093
00094 Eh_ndgrid eh_reshape_ndgrid( Eh_ndgrid g , gssize *new_size , gssize new_n_dim )
00095 {
00096 gssize k_old, k_new;
00097 gssize n;
00098
00099 for ( n=0 ; n<g->n_dim ; n++ )
00100 {
00101 k_old *= g->size[n];
00102 k_new *= new_size[n];
00103 }
00104 eh_require( k_old == k_new );
00105
00106 if ( new_n_dim > g->n_dim )
00107 {
00108 g->x = g_renew( double* , g->x , new_n_dim );
00109 for ( n=0 ; n<g->n_dim ; n++ )
00110 g->x[n] = g_renew( double , g->x[n] , new_size[n] );
00111 for ( n=g->n_dim ; n<new_n_dim ; n++ )
00112 g->x[n] = eh_new( double , new_size[n] );
00113 }
00114 else
00115 {
00116 for ( n=0 ; n<new_n_dim ; n++ )
00117 g->x[n] = g_renew( double , g->x[n] , new_size[n] );
00118 for ( n=new_n_dim ; n<g->n_dim ; n++ )
00119 eh_free( g->x[n] );
00120 g->x = g_renew( double* , g->x , new_n_dim );
00121 }
00122
00123 g->n_dim = new_n_dim;
00124 g->size = g_renew( gssize , g->size , new_n_dim );
00125 for ( n=0 ; n<g->n_dim ; n++ )
00126 g->size[n] = new_size[n];
00127
00128 return g;
00129 }
00130
00131 gssize eh_ndgrid_sub_to_id( gssize *size , gssize *sub , gssize n_dim )
00132 {
00133 gssize n;
00134 gssize *k;
00135 gssize id;
00136
00137 k = eh_new( gssize , n_dim );
00138 for ( n=1,k[0]=1 ; n<n_dim ; n++ )
00139 k[n] = k[n-1]*size[n-1];
00140
00141 for ( n=0 ; n<n_dim ; n++ )
00142 id += sub[n]*k[n];
00143
00144 eh_free( k );
00145
00146 return id;
00147 }
00148
00149 gssize *eh_ndgrid_id_to_sub( gssize *size , gssize id , gssize n_dim )
00150 {
00151 gssize n;
00152 gssize *k;
00153 gssize *sub;
00154
00155 sub = eh_new( gssize , n_dim );
00156 k = eh_new( gssize , n_dim );
00157
00158 for ( n=1,k[0]=1 ; n<n_dim ; n++ )
00159 k[n] = k[n-1]*size[n-1];
00160
00161 for ( n=n_dim-1 ; n>=0 ; n-- )
00162 {
00163 sub[n] = id/k[n];
00164 id = id%k[n];
00165 }
00166
00167 eh_free( k );
00168
00169 return sub;
00170 }
00171
00172 void eh_ndgrid_destroy( Eh_ndgrid g )
00173 {
00174 eh_free_ndgrid_data( g );
00175 eh_free( g );
00176 }
00177
00178 Eh_dbl_grid eh_ndgrid_to_grid( Eh_ndgrid g )
00179 {
00180 Eh_dbl_grid dest;
00181 gssize i, n, n_x, n_y;
00182
00183
00184 for ( n=0 ; n<g->n_dim && g->size[n]==1 ; n++ );
00185
00186 if ( n!=g->n_dim )
00187 {
00188
00189
00190
00191
00192 n_y = g->size[g->n_dim-1];
00193 for ( n_x=1 ; n<g->n_dim-1 ; n++ )
00194 n_x *= g->size[n];
00195 }
00196 else
00197 {
00198 n_x = 1;
00199 n_y = 1;
00200 }
00201
00202 dest = eh_grid_new( double , n_x , n_y );
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 {
00221 double** dest_data = eh_dbl_grid_data( dest );
00222 eh_free( dest_data[0] );
00223 dest_data[0] = g->data;
00224 for ( i=1 ; i<n_x ; i++ )
00225 dest_data[i] = dest_data[i-1]+n_y;
00226 }
00227
00228 memcpy( eh_grid_x(dest) , g->x[0] , sizeof(double)*g->size[0] );
00229
00230 return dest;
00231 }
00232
00233 Eh_ndgrid eh_grid_to_ndgrid( Eh_grid g )
00234 {
00235 Eh_ndgrid dest;
00236
00237 NEW_OBJECT( Eh_ndgrid , dest );
00238
00239 dest->n_dim = 2;
00240
00241 dest->x = eh_new( double* , 2 );
00242 dest->x[0] = eh_new( double , eh_grid_n_x(g) );
00243 dest->x[1] = eh_new( double , eh_grid_n_y(g) );
00244 memcpy( dest->x[0] , eh_grid_x(g) , sizeof(double)*eh_grid_n_x(g) );
00245 memcpy( dest->x[1] , eh_grid_y(g) , sizeof(double)*eh_grid_n_x(g) );
00246
00247 dest->data = (double*)eh_grid_data_start(g);
00248
00249 dest->size = eh_new( gssize , 2 );
00250 dest->size[0] = eh_grid_n_x(g);
00251 dest->size[1] = eh_grid_n_y(g);
00252
00253 return dest;
00254 }
00255
00256 gssize eh_ndgrid_write( FILE *fp , Eh_ndgrid g )
00257 {
00258 gssize n, n_x;
00259 for ( n=0,n_x=1 ; n<g->n_dim ; n++ )
00260 n_x *= g->size[n];
00261 return eh_dbl_array_write( fp , g->data , n_x );
00262 }
00263
00264 #endif
00265