Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

expr-inline.h

Go to the documentation of this file.
00001 // Expression implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2001-2003 Hermann Schichl
00004 //
00005 // This file is part of the COCONUT API.  This library
00006 // is free software; you can redistribute it and/or modify it under the
00007 // terms of the Library GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library 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 // Library GNU General Public License for more details.
00015 
00016 // As a special exception, you may use this file as part of a free software
00017 // library without restriction.  Specifically, if other files instantiate
00018 // templates or use macros or inline functions from this file, or you compile
00019 // this file and link it with other files to produce an executable, this
00020 // file does not by itself cause the resulting executable to be covered by
00021 // the Library GNU General Public License.  This exception does not however
00022 // invalidate any other reasons why the executable file might be covered by
00023 // the Library GNU General Public License.
00024 
00027 #ifndef _EXPR_INLINE_H_
00028 #define _EXPR_INLINE_H_
00029 
00030 class expression_node::parents_compare :
00031       public std::binary_function<expression_node, expression_node, bool>
00032 {
00033 public:
00034   bool operator()(const expression_node& __x, const expression_node& __y)
00035   const
00036   {
00037     if(__x.operator_type == __y.operator_type)
00038     {
00039       switch(__x.operator_type)
00040       {
00041         case EXPRINFO_GHOST:
00042           if(__x.node_num != __y.node_num)
00043             return __x.node_num < __y.node_num;
00044           break;
00045         case EXPRINFO_VARIABLE:
00046           if(__x.params.nn() != __y.params.nn())
00047             return __x.params.nn() < __y.params.nn();
00048           break;
00049         case EXPRINFO_CONSTANT:
00050           if(__x.params.is_allocated() != __y.params.is_allocated())
00051             return __x.params.is_allocated() < __y.params.is_allocated();
00052           if(__x.params.is_allocated())
00053           {
00054             if(__x.params.d() != __y.params.d())
00055               return __x.params.d() < __y.params.d();
00056           }
00057           else
00058           {
00059             if(__x.params.nd() != __y.params.nd())
00060               return __x.params.nd() < __y.params.nd();
00061           }
00062           break;
00063       }
00064       if(__x.n_children == __y.n_children)
00065         return __x.node_num < __y.node_num;
00066       return __x.n_children < __y.n_children;
00067     }
00068     return __x.operator_type < __y.operator_type;
00069   }
00070 };
00071 
00072 class expression_node::children_compare :
00073       public std::binary_function<expression_node, expression_node, bool>
00074 {
00075 public:
00076   bool operator()(const expression_node& __x, const expression_node& __y)
00077   const
00078   {
00079     if(__x.sem.degree != __y.sem.degree)
00080       return __x.sem.degree < __y.sem.degree;
00081     if(__x.sem.dim != __y.sem.dim)
00082       return __x.sem.dim < __y.sem.dim;
00083     if(__x.operator_type == __y.operator_type)
00084     {
00085       switch(__x.operator_type)
00086       {
00087         case EXPRINFO_GHOST:
00088           if(__x.node_num != __y.node_num)
00089             return __x.node_num < __y.node_num;
00090           break;
00091         case EXPRINFO_VARIABLE:
00092           if(__x.params.nn() != __y.params.nn())
00093             return __x.params.nn() < __y.params.nn();
00094           break;
00095         case EXPRINFO_CONSTANT:
00096           if(__x.params.is_allocated() != __y.params.is_allocated())
00097             return __x.params.is_allocated() < __y.params.is_allocated();
00098           if(__x.params.is_allocated())
00099           {
00100             if(__x.params.d() != __y.params.d())
00101               return __x.params.d() < __y.params.d();
00102           }
00103           else
00104           {
00105             if(__x.params.nd() != __y.params.nd())
00106               return __x.params.nd() < __y.params.nd();
00107           }
00108           break;
00109       }
00110       if(__x.n_children == __y.n_children)
00111         return __x.node_num < __y.node_num;
00112       return __x.n_children < __y.n_children;
00113     }
00114     return __x.operator_type < __y.operator_type;
00115   }
00116 };
00117 
00118 class expression_node::parents_compare_eq :
00119       public std::binary_function<expression_node, expression_node, bool>
00120 {
00121 public:
00122   bool operator()(const expression_node& __x, const expression_node& __y)
00123   const
00124   {
00125     if(__x.n_children != __y.n_children)
00126       return false;
00127     if(__x.operator_type == __y.operator_type)
00128     {
00129       switch(__x.operator_type)
00130       {
00131         case EXPRINFO_GHOST:
00132           return __x.node_num == __y.node_num;
00133           break;
00134         case EXPRINFO_VARIABLE:
00135           return __x.params.nn() == __y.params.nn();
00136           break;
00137         case EXPRINFO_CONSTANT:
00138           if(__x.params.is_allocated() != __y.params.is_allocated())
00139             return false;
00140           if(__x.params.is_allocated())
00141             return __x.params.d() == __y.params.d();
00142           else
00143             return __x.params.nd() == __y.params.nd();
00144           break;
00145         case EXPRINFO_SUM:
00146         case EXPRINFO_MAX:
00147         case EXPRINFO_MIN:
00148         case EXPRINFO_SQUARE:
00149         case EXPRINFO_SQROOT:
00150         case EXPRINFO_ABS:
00151         case EXPRINFO_POW:
00152         case EXPRINFO_EXP:
00153         case EXPRINFO_LOG:
00154         case EXPRINFO_SIN:
00155         case EXPRINFO_COS:
00156           if(__x.params.nd() != __y.params.nd())
00157             return false;
00158           /* no break! */
00159         case EXPRINFO_ATAN2:
00160           {
00161             std::vector<double>::const_iterator _bx, _by;
00162 
00163             for(_bx = __x.coeffs.begin(), _by = __y.coeffs.begin();
00164                 _bx != __x.coeffs.end(); ++_bx, ++_by)
00165             {
00166               if(*_bx != *_by) return false;
00167             }
00168           }
00169           break;
00170         case EXPRINFO_PROD:
00171         case EXPRINFO_INVERT:
00172         case EXPRINFO_DIV:
00173           if(__x.params.nd() != __y.params.nd())
00174             return false;
00175           break;
00176         case EXPRINFO_INTPOWER:
00177           if(__x.params.nn() != __y.params.nn() ||
00178              __x.coeffs[0] != __y.coeffs[0])
00179             return false;
00180           break;
00181         case EXPRINFO_GAUSS:
00182           if(__x.params.d()[0] != __y.params.d()[0] ||
00183              __x.params.d()[1] != __y.params.d()[1] ||
00184              __x.coeffs[0] != __y.coeffs[0])
00185             return false;
00186           break;
00187         case EXPRINFO_POLY:
00188           std::cerr << "Polynomes NYI" << std::endl;
00189           throw "NYI";
00190           break;
00191         case EXPRINFO_LIN:
00192         case EXPRINFO_QUAD:
00193         default:
00194           return false;
00195           break;
00196       }
00197       return true;
00198     }
00199     return false;
00200   }
00201 };
00202   
00203 
00204 inline bool expression_node::operator<(const expression_node& __x) const
00205 {
00206   return this->node_num < __x.node_num;
00207 }
00208 
00209 // writing
00210 class expression_print_visitor : public preorder_visitor<expression_node, int>
00211 {
00212   int n;
00213   int nnum;
00214   std::ostream& o;
00215   std::vector<bool>* printed;
00216 public:
00217   expression_print_visitor(std::vector<bool>& __p, std::ostream& __o = std::cout)
00218     : o(__o)
00219     { printed = &__p; }
00220   expression_print_visitor(const expression_print_visitor& __p) : o(__p.o)
00221      { n = __p.n; nnum = __p.nnum; printed = __p.printed; }
00222   ~expression_print_visitor() {}
00223 
00224   bool preorder(const expression_node &r)
00225         { n = 0;
00226           nnum = r.node_num;
00227           if((int)(*printed).size() <= nnum)
00228             (*printed).insert((*printed).end(), nnum - (*printed).size()+1,
00229                               false);
00230           if(!(*printed)[nnum])
00231           {
00232             (*printed)[nnum] = true;
00233             o << r;
00234           }
00235           else /* a node has to be walked only once */
00236             return false;
00237           return true;
00238         }
00239   int vvalue() { return -1; }
00240   int value() { return nnum; }
00241   void collect(const expression_node &r, int __r)
00242          { 
00243            if(__r >= 0)
00244            {
00245              o << "<E> " << r.node_num << ' ' << __r << ' ' <<
00246                r.coeffs[n] << std::endl;
00247              n++;
00248            }
00249          }
00250 };
00251 
00252 inline std::ostream& __wr_interval(std::ostream& o, const interval& __i)
00253 {
00254   if(__i.inf() != -INFINITY || __i.sup() != INFINITY)
00255   {
00256     o << "[";
00257     if(__i.inf() == -INFINITY)
00258       o << "-I";
00259     else
00260       o << __i.inf();
00261     o << ",";
00262       if(__i.sup() == INFINITY)
00263     o << "I";
00264       else
00265     o << __i.sup();
00266     o << "]";
00267   }
00268   return o;
00269 }
00270 
00271 //#include <expression.cc>
00272 #endif /* _EXPR_INLINE_H_ */

Generated on Tue Nov 4 01:57:57 2003 for COCONUT API by doxygen1.2.18