Ignore:
Timestamp:
04/13/18 14:29:20 (3 years ago)
Author:
ymipsl
Message:

Enhencement :

For expression, can now compare a value or array with a missing value.

Expression like "field == $missing_value" or "scalar == $missing_value" return true where value is missing_value
Expression like "field != $missing_value" or "scalar != $missing_value" return false where value is missing_value

YM

File:
1 edited

Legend:

Unmodified
Added
Removed
  • XIOS/dev/XIOS_DEV_CMIP6/src/parse_expr/operator_expr.hpp

    r1158 r1481  
    77#include "exception.hpp" 
    88#include "array_new.hpp" 
     9#include "utils.hpp" 
    910 
    1011using namespace std; 
     
    253254    static inline double div_ss(double x, double y)   { return x / y; } 
    254255    static inline double pow_ss(double x, double y)   { return std::pow(x,y); } 
    255     static inline double eq_ss(double x, double y)    { return x == y; } 
     256 
     257    static inline double eq_ss(double x, double y) // specific check for NaN 
     258    { 
     259       bool xNan=NumTraits<double>::isNan(x) ; 
     260       bool yNan=NumTraits<double>::isNan(y) ; 
     261       if (xNan && yNan) return true ; 
     262       else if (xNan) return false ; 
     263       else if (yNan) return false ; 
     264       else return x == y; 
     265    } 
     266     
    256267    static inline double lt_ss(double x, double y)    { return x < y; } 
    257268    static inline double gt_ss(double x, double y)    { return x > y; } 
    258269    static inline double le_ss(double x, double y)    { return x <= y; } 
    259270    static inline double ge_ss(double x, double y)    { return x >= y; } 
    260     static inline double ne_ss(double x, double y)    { return x != y; } 
    261  
     271 
     272    static inline double ne_ss(double x, double y) // specific check for NaN 
     273    { 
     274       bool xNan=NumTraits<double>::isNan(x) ; 
     275       bool yNan=NumTraits<double>::isNan(y) ; 
     276       if (xNan && yNan) return false ; 
     277       else if (xNan) return true ; 
     278       else if (yNan) return true ;       
     279       else return x != y; 
     280    } 
     281     
    262282    static inline CArray<double,1> neg_f(const CArray<double,1>& x)   { return Array<double,1>(-x); } 
    263283    static inline CArray<double,1> cos_f(const CArray<double,1>& x)   { return Array<double,1>(cos(x)); } 
     
    286306    static inline CArray<double,1> div_fs(const CArray<double,1>& x, double y)   { return Array<double,1>(x / y); } 
    287307    static inline CArray<double,1> pow_fs(const CArray<double,1>& x, double y)   { return Array<double,1>(pow(x,y)); } 
    288     static inline CArray<double,1> eq_fs(const CArray<double,1>& x, double y)    { return Array<double,1>(x == y); } 
     308 
     309    static inline CArray<double,1> eq_fs(const CArray<double,1>& x, double y) // specific check for NaN 
     310    { 
     311      if (NumTraits<double>::isNan(y)) 
     312      { 
     313        CArray<double,1> ret(x.numElements()) ; 
     314        Array<double,1>::const_iterator itx=x.begin(),itxe=x.end(); 
     315        Array<double,1>::iterator itret=ret.begin() ; 
     316        for(;itx!=itxe;++itx,++itret) *itret=NumTraits<double>::isNan(*itx) ; 
     317        return ret ; 
     318      } 
     319      else return Array<double,1>(x == y);  
     320    } 
     321     
    289322    static inline CArray<double,1> lt_fs(const CArray<double,1>& x, double y)    { return Array<double,1>(x < y); } 
    290323    static inline CArray<double,1> gt_fs(const CArray<double,1>& x, double y)    { return Array<double,1>(x > y); } 
    291324    static inline CArray<double,1> le_fs(const CArray<double,1>& x, double y)    { return Array<double,1>(x <= y); } 
    292325    static inline CArray<double,1> ge_fs(const CArray<double,1>& x, double y)    { return Array<double,1>(x >= y); } 
    293     static inline CArray<double,1> ne_fs(const CArray<double,1>& x, double y)    { return Array<double,1>(x != y); } 
     326 
     327    static  inline CArray<double,1> ne_fs(const CArray<double,1>& x, double y) // specific check for NaN 
     328    { 
     329      if (NumTraits<double>::isNan(y)) 
     330      { 
     331        CArray<double,1> ret(x.numElements()) ; 
     332        Array<double,1>::const_iterator itx=x.begin(),itxe=x.end(); 
     333        Array<double,1>::iterator itret=ret.begin() ; 
     334        for(;itx!=itxe;++itx,++itret) *itret = !NumTraits<double>::isNan(*itx) ; 
     335        return ret ; 
     336      } 
     337      else return Array<double,1>(x != y);  
     338    } 
    294339 
    295340    static inline CArray<double,1> add_sf(double x, const CArray<double,1>& y)   { return Array<double,1>(x + y); } 
     
    297342    static inline CArray<double,1> mult_sf(double x, const CArray<double,1>& y)  { return Array<double,1>(x * y); } 
    298343    static inline CArray<double,1> div_sf(double x, const CArray<double,1>& y)   { return Array<double,1>(x / y); } 
    299     static inline CArray<double,1> eq_sf(double x, const CArray<double,1>& y)    { return Array<double,1>(x == y); } 
     344 
     345    static inline CArray<double,1> eq_sf(double x, const CArray<double,1>& y) // specific check for NaN 
     346    { 
     347      if (NumTraits<double>::isNan(x)) 
     348      { 
     349        CArray<double,1> ret(y.numElements()) ; 
     350        Array<double,1>::const_iterator ity=y.begin(),itye=y.end(); 
     351        Array<double,1>::iterator itret=ret.begin() ; 
     352        for(;ity!=itye;++ity,++itret) *itret=NumTraits<double>::isNan(*ity) ; 
     353        return ret ; 
     354      } 
     355      else return Array<double,1>(x == y);  
     356    } 
    300357    static inline CArray<double,1> lt_sf(double x, const CArray<double,1>& y)    { return Array<double,1>(x < y); } 
    301358    static inline CArray<double,1> gt_sf(double x, const CArray<double,1>& y)    { return Array<double,1>(x > y); } 
    302359    static inline CArray<double,1> le_sf(double x, const CArray<double,1>& y)    { return Array<double,1>(x <= y); } 
    303360    static inline CArray<double,1> ge_sf(double x, const CArray<double,1>& y)    { return Array<double,1>(x >= y); } 
    304     static inline CArray<double,1> ne_sf(double x, const CArray<double,1>& y)    { return Array<double,1>(x != y); } 
    305  
    306  
     361 
     362    static inline CArray<double,1> ne_sf(double x, const CArray<double,1>& y) // specific check for NaN 
     363    { 
     364      if (NumTraits<double>::isNan(x)) 
     365      { 
     366        CArray<double,1> ret(y.numElements()) ; 
     367        Array<double,1>::const_iterator ity=y.begin(),itye=y.end(); 
     368        Array<double,1>::iterator itret=ret.begin() ; 
     369        for(;ity!=itye;++ity,++itret) *itret=!NumTraits<double>::isNan(*ity) ; 
     370        return ret ; 
     371      } 
     372      else return Array<double,1>(x != y); 
     373    } 
    307374    static inline double cond_sss(double x, double y, double z)   { return (x==0) ? z : y ; } 
    308375 
Note: See TracChangeset for help on using the changeset viewer.