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

Go to the documentation of this file.
00001 #include <eh_utils.h>
00002 
00005 CLASS( Eh_input_val )
00006 {
00007    Eh_input_val_type type;    //< The type of Eh_input_val.  This defines the way the value changes.
00008    FILE*             fp;      //< Pointer to a user-specified file, if necessary.  NULL, otherwise.
00009    gchar*            file;    //< The name of a user-specified file, if necessary.  NULL, otherwise.
00010    double*           x;       //< Array of x-values for a time series or a user-defined CDF
00011    double*           y;       //< Array of y-values for a time series or a user-defined CDF
00012    double            len;     //< Length of \a x and \a y
00013    GRand*            rand;    //< A random number generator, if necessary.  NULL, otherwise.
00014    double            data[2]; //< Data used to calculate a new value
00015    double            val;     //< The current value of the Eh_input_val
00016 };
00017 
00018 GQuark
00019 eh_input_val_error_quark( void )
00020 {
00021    return g_quark_from_static_string( "eh-input-val-error-quark" );
00022 }
00023 
00030 Eh_input_val
00031 eh_input_val_new( )
00032 {
00033    Eh_input_val val;
00034 
00035    NEW_OBJECT( Eh_input_val , val );
00036 
00037    if ( val )
00038    {
00039       val->fp        = NULL;
00040       val->file      = NULL;
00041       val->x         = NULL;
00042       val->y         = NULL;
00043       val->len       = 0;
00044       val->val       = G_MINDOUBLE;
00045       val->rand      = g_rand_new();
00046    }
00047 
00048    return val;
00049 }
00050 
00057 Eh_input_val
00058 eh_input_val_destroy( Eh_input_val val )
00059 {
00060    if ( val )
00061    {
00062       eh_free( val->x         );
00063       eh_free( val->y         );
00064       eh_free( val->file      );
00065       g_rand_free( val->rand );
00066       eh_free( val );
00067    }
00068    return NULL;
00069 }
00070 
00095 Eh_input_val
00096 eh_input_val_set( const char *input_str , GError** err )
00097 {
00098    Eh_input_val val = NULL;
00099 
00100    eh_return_val_if_fail( err==NULL || *err==NULL , NULL );
00101 
00102    eh_require( input_str );
00103 
00104    //---
00105    // Search input_str for '='.  If the string contains '=' then it is of
00106    // the form "FILE=filename", "UNIFORM=x,y", or "NORMAL=x,y".  Otherwise,
00107    // the string should be a string representation of a number.
00108    //---
00109    if ( strchr( input_str , '=' ) == NULL )
00110    {
00111       val = eh_input_val_new();
00112 
00113       val->type = EH_INPUT_VAL_SCALAR;
00114       val->val = g_ascii_strtod( input_str , NULL );
00115    }
00116    else
00117    {
00118       GError* tmp_error = NULL;
00119       char **equal_split = g_strsplit( input_str , "=" , 2 );
00120 
00121       if (    g_ascii_strcasecmp( equal_split[0] , "FILE" ) == 0 
00122            || g_ascii_strcasecmp( equal_split[0] , "USER" ) == 0  )
00123       {
00124          double** data;
00125          gint n_rows, n_cols;
00126          Eh_input_val_type type;
00127          gchar* file;
00128 
00129          if ( g_ascii_strcasecmp( equal_split[0] , "FILE" ) == 0 )
00130             type = EH_INPUT_VAL_FILE;
00131          else
00132             type = EH_INPUT_VAL_RAND_USER;
00133 
00134          file = g_strdup( equal_split[1] );
00135 
00136          data = eh_dlm_read_swap( file , ";," , &n_rows , &n_cols , &tmp_error );
00137 
00138          if ( !tmp_error )
00139          {
00140             if ( n_rows!=2 )
00141                g_set_error( &tmp_error ,
00142                             EH_INPUT_VAL_ERROR ,
00143                             EH_INPUT_VAL_ERROR_NOT_TWO_COLUMNS ,
00144                             "%s: Input file does not contain 2 columns (found %d)\n" ,
00145                             file , n_rows );
00146             else if ( !eh_dbl_array_is_monotonic_up( data[0] , n_cols ) )
00147                g_set_error( &tmp_error ,
00148                             EH_INPUT_VAL_ERROR ,
00149                             EH_INPUT_VAL_ERROR_X_NOT_MONOTONIC ,
00150                             "%s: The first column must be monotonically increasing\n" ,
00151                             file );
00152             else if (    type == EH_INPUT_VAL_RAND_USER
00153                       && !eh_dbl_array_is_monotonic_up( data[1] , n_cols ) )
00154                g_set_error( &tmp_error ,
00155                             EH_INPUT_VAL_ERROR ,
00156                             EH_INPUT_VAL_ERROR_F_NOT_MONOTONIC ,
00157                             "%s: The second column must be monotonically increasing\n" ,
00158                             file );
00159             else if (    type == EH_INPUT_VAL_RAND_USER
00160                       && !(data[1][0]<=0 && data[1][n_cols-1]>=1. ) )
00161                g_set_error( &tmp_error ,
00162                             EH_INPUT_VAL_ERROR ,
00163                             EH_INPUT_VAL_ERROR_BAD_F_RANGE ,
00164                             "%s: CDF data must range from 0 to 1 (found [%f,%f]).\n" ,
00165                             file , data[1][0] , data[1][n_cols-1] );
00166             else
00167             {
00168                val = eh_input_val_new();
00169 
00170                val->type = type;
00171                val->file = file;
00172                val->len = n_cols;
00173                val->x   = g_memdup( data[0] , sizeof(double)*n_cols );
00174                val->y   = g_memdup( data[1] , sizeof(double)*n_cols );
00175             }
00176          }
00177 
00178          eh_free_2( data );
00179       }
00180       else if (    g_ascii_strcasecmp( equal_split[0] , "UNIFORM" ) == 0 
00181                 || g_ascii_strcasecmp( equal_split[0] , "NORMAL"  ) == 0 
00182                 || g_ascii_strcasecmp( equal_split[0] , "WEIBULL" ) == 0 )
00183       {
00184          char** comma_split = g_strsplit( equal_split[1] , "," , -1 );
00185          gint   n_vals      = g_strv_length( comma_split );
00186 
00187          if ( n_vals != 2 )
00188             g_set_error( &tmp_error ,
00189                          EH_INPUT_VAL_ERROR ,
00190                          EH_INPUT_VAL_ERROR_NOT_TWO_DIST_VALS ,
00191                          "%s: Two values are required to define a distribution (found %d)." ,
00192                          equal_split[1], n_vals );
00193          else
00194          {
00195             val = eh_input_val_new();
00196 
00197             val->data[0] = g_ascii_strtod( comma_split[0] , NULL );
00198             val->data[1] = g_ascii_strtod( comma_split[1] , NULL );
00199 
00200             if      ( g_ascii_strcasecmp( equal_split[0] , "UNIFORM" ) == 0 )
00201                val->type = EH_INPUT_VAL_RAND_UNIFORM;
00202             else if ( g_ascii_strcasecmp( equal_split[0] , "NORMAL"  ) == 0 )
00203                val->type = EH_INPUT_VAL_RAND_NORMAL;
00204             else if ( g_ascii_strcasecmp( equal_split[0] , "WEIBULL" ) == 0 )
00205                val->type = EH_INPUT_VAL_RAND_WEIBULL;
00206             else
00207                eh_require_not_reached();
00208 
00209          }
00210          g_strfreev( comma_split );
00211       }
00212       else
00213       {
00214          g_set_error( &tmp_error ,
00215                       EH_INPUT_VAL_ERROR ,
00216                       EH_INPUT_VAL_ERROR_BAD_DIST_KEY ,
00217                       "%s: Bad input val key (valid keys are %s).\n" ,
00218                       equal_split[0] , "Uniform, Normal, Weibull, User, and File" );
00219       }
00220 
00221       g_strfreev( equal_split );
00222 
00223       if ( tmp_error )
00224          g_propagate_error( err , tmp_error );
00225    }
00226    
00227    return val;
00228 }
00229 
00238 double
00239 eh_input_val_eval( Eh_input_val val , ... )
00240 {
00241    va_list args;
00242    double data;
00243 
00244    if ( val->type == EH_INPUT_VAL_RAND_NORMAL )
00245       val->val = eh_rand_normal( val->rand , val->data[0] , val->data[1] );
00246    else if ( val->type == EH_INPUT_VAL_RAND_UNIFORM )
00247       val->val = g_rand_double_range( val->rand , val->data[0] , val->data[1] );
00248    else if ( val->type == EH_INPUT_VAL_RAND_WEIBULL )
00249       val->val = eh_rand_weibull( val->rand , val->data[0] , val->data[1] );
00250    else if ( val->type == EH_INPUT_VAL_RAND_USER )
00251       val->val = eh_rand_user( val->rand , val->x , val->y , val->len );
00252    else if ( val->type == EH_INPUT_VAL_FILE )
00253    {
00254 
00255       eh_require( val->x );
00256       eh_require( val->y );
00257 
00258       va_start( args , val );
00259       data = va_arg( args , double );
00260 
00261       interpolate( val->x , val->y , val->len , &data , &(val->val) , 1 );
00262 
00263       va_end( args );
00264    }
00265 
00266    return val->val;
00267 }
00268 
00269 

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