FAUST compiler  0.9.9.6b8
interval.hh
Go to the documentation of this file.
00001 /************************************************************************
00002  ************************************************************************
00003     FAUST compiler
00004     Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
00005     ---------------------------------------------------------------------
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  ************************************************************************
00020  ************************************************************************/
00021  
00022  
00023  
00024 #ifndef __signals_intervals__
00025 #define __signals_intervals__
00026 
00027 #include <math.h>
00028 #include <iostream>
00029 
00030 #ifdef WIN32
00031 inline double log2(double e) { return log(e)/log(double(2)); }
00032 #endif
00033 
00034 using namespace std;
00035 
00036 struct interval 
00037 {
00038     bool    valid;          
00039     double  lo;             
00040     double  hi;             
00041     
00042     interval ()                     : valid(false), lo(-HUGE_VAL), hi(HUGE_VAL) {}
00043     interval (double n)             : valid(true), lo(n), hi(n) {}
00044     interval (double n, double m)   : valid(true), lo(min(n,m)), hi(max(n,m)) {}
00045     interval (const interval& r)    : valid(r.valid), lo(r.lo), hi(r.hi) {}
00046     
00047     bool isconst() { return valid & (lo == hi); }
00048 };
00049 
00050 inline ostream& operator<<(ostream& dst, const interval& i)     
00051 { 
00052     if (i.valid) {
00053         return  dst << "interval(" << i.lo << ", " << i.hi << ")";
00054     } else {
00055         return  dst << "interval()";
00056     }
00057 }
00058 
00059 inline double min(double x, double y) { return (x<y) ? x:y; }
00060 inline double max(double x, double y) { return (x>y) ? x:y; }
00061 inline double min4(double a, double b, double c, double d)  { return min(min(a,b),min(c,d)); }
00062 inline double max4(double a, double b, double c, double d)  { return max(max(a,b),max(c,d)); }
00063 
00064 inline interval reunion(const interval& x, const interval& y)
00065 {
00066     if (x.valid & y.valid) {
00067         return interval(min(x.lo,y.lo), max(x.hi,y.hi));
00068     } else {
00069         return interval();
00070     }
00071 }
00072 
00073 
00074 inline interval operator+(const interval& x, const interval& y)     
00075 { 
00076     return (x.valid&y.valid) ? interval(x.lo+y.lo, x.hi+y.hi) : interval(); 
00077 }
00078 
00079 inline interval operator-(const interval& x, const interval& y)     
00080 { 
00081     return (x.valid & y.valid) ? interval(x.lo-y.hi, x.hi-y.lo) : interval();; 
00082 }
00083 
00084 inline interval operator*(const interval& x, const interval& y)     
00085 { 
00086     if (x.valid&y.valid) {
00087         double a=x.lo*y.lo; 
00088         double b=x.lo*y.hi; 
00089         double c=x.hi*y.lo; 
00090         double d=x.hi*y.hi;
00091         return interval(min4(a,b,c,d), max4(a,b,c,d));
00092     } else {
00093         return interval();
00094     }
00095 }
00096 
00097 inline interval operator/(const interval& x, const interval& y)
00098 {
00099     return (x.valid && y.valid && (y.lo > 0 | y.hi < 0)) 
00100             ? x * interval(1/y.hi,1/y.lo)
00101             : interval();
00102 }
00103 
00104 inline interval operator%(const interval& x, const interval& y)
00105 {
00106     return (x.valid && y.valid && x.lo >= 0 && y.lo > 0) 
00107             ? interval(0,y.hi)
00108             : interval();
00109 }
00110 
00114 inline int bitmask (double x)   {
00115     int v = int(x);
00116     for (int i=1; i<32; i*=2)   { v |= v>>i; }
00117     return v;
00118 }
00119 
00120 //----------------------booleans&bits--------------------------------------
00121 
00122 inline interval operator&(const interval& x, const interval& y)
00123 {
00124     if (x.valid && y.valid) {
00125         if (x.lo >= 0 & y.lo >= 0) {
00126             return interval(0, bitmask(x.hi) & bitmask(y.hi));
00127         } else if (y.lo >= 0) {
00128             return interval(0, bitmask(y.hi));
00129         } else if (x.lo >= 0) {
00130             return interval(0, bitmask(y.hi));
00131         } else {
00132             return interval();
00133         }
00134     } else if (x.valid & x.lo >= 0) {
00135         return interval(0, bitmask(x.hi));
00136     } else if (y.valid & y.lo >= 0) {
00137         return interval(0, bitmask(y.hi));
00138     } else {
00139         return interval();
00140     }
00141 }
00142 
00143 inline interval operator|(const interval& x, const interval& y)
00144 {
00145     if (x.valid && y.valid && x.lo >= 0 && y.lo >= 0) {
00146         return interval(0, bitmask(x.hi) | bitmask(y.hi));
00147     } else {
00148         return interval();
00149     }
00150 }
00151 
00152 inline interval operator^(const interval&, const interval&)
00153 {
00154     return interval();
00155 }
00156 
00157 inline interval operator<<(const interval&, const interval&)
00158 {
00159     return interval();
00160 }
00161 
00162 inline interval operator>>(const interval&, const interval&)
00163 {
00164     return interval();
00165 }
00166 
00167 // ---------------------comparaisons------------------------------
00168 // note : les comparaisons ne portent pas sur les intervals 
00169 // mais l'interval des comparaisons de signaux
00170 
00171 inline interval operator<(const interval&, const interval&)
00172 {
00173     return interval(0,1);
00174 }
00175 
00176 inline interval operator<=(const interval&, const interval&)
00177 {
00178     return interval(0,1);
00179 }
00180 
00181 inline interval operator>(const interval&, const interval&)
00182 {
00183     return interval(0,1);
00184 }
00185 
00186 inline interval operator>=(const interval&, const interval&)
00187 {
00188     return interval(0,1);
00189 }
00190 
00191 inline interval operator==(const interval&, const interval&)
00192 {
00193     return interval(0,1);
00194 }
00195 
00196 inline interval operator!=(const interval&, const interval&)
00197 {
00198     return interval(0,1);
00199 }
00200 
00201 //-----------------------------------------------------------------------
00202 
00203 inline interval min(const interval& x, const interval& y)
00204 {
00205     return interval(min(x.lo,y.lo), min(x.hi,y.hi));
00206 }
00207 
00208 inline interval max(const interval& x, const interval& y)
00209 {
00210     return interval(max(x.lo,y.lo), max(x.hi,y.hi));
00211 }
00212         
00213 inline interval abs(const interval& x)
00214 {
00215     if (x.valid) {
00216         if (x.lo >= 0) {
00217             return x;
00218         } else if (x.hi < 0) {
00219             return interval(fabs(x.hi), fabs(x.lo));
00220         } else {
00221             return interval(0, max(fabs(x.lo), x.hi));
00222         }
00223     } else {
00224         return x;
00225     }
00226 }       
00227 
00228 #endif