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

expression.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 _EXPRESSION_H_
00028 #define _EXPRESSION_H_
00029 
00030 #include <stdarg.h>
00031 #include <stdio.h>
00032 #include <dag.h>
00033 #include <visitor.h>
00034 #include <interval.h>
00035 #include <coconut_config.h>
00036 #include <semantics.h>
00037 #include <evaluator.h>          // not yet designed
00038 #include <g_algo.h>
00039 #include <fstream>
00040 #include <cerrno>
00041 #include <string>
00042 #include <utility>
00043 #include <values.h>
00044 #include <linalg.h>
00045 
00046 using namespace vgtl;
00047 
00048 // another very well possible approach would be to use
00049 // a base expression class and derived classes for every
00050 // expression type known. I have, however, no idea which
00051 // method performs better. I would never remove the expression
00052 // type flag, though.
00053 
00054 // don't renumber these w/o thinking
00055 #define EXPRINFO_GHOST          0       // number is overlayed params.b
00056                                         // contains info on edge deletion
00057 #define EXPRINFO_CONSTANT       -1      // contained in params.d or .nd 
00058 #define EXPRINFO_VARIABLE       -2      // index contained in params.nn
00059 
00060 // renumbering these should be safe
00061 
00062 // these have an arbitrary number of arguments
00063 #define EXPRINFO_SUM            -3      // params.nd contains additive const
00064 #define EXPRINFO_MEAN           -4      // no params
00065 #define EXPRINFO_PROD           -5      // params.nd contains multiplic. const
00066 #define EXPRINFO_MAX            -6      // params.nd contains min value
00067 #define EXPRINFO_MIN            -7      // params.nd contains max value
00068 #define EXPRINFO_MONOME         -8      // params.n contains the exponents
00069 #define EXPRINFO_SCPROD         -9      // no params
00070 #define EXPRINFO_NORM          -10      // params.nd contains the norm-type
00071 
00072 // these are one dimensional
00073 #define EXPRINFO_INVERT        -11      // params.nd/x
00074 #define EXPRINFO_SQUARE        -12      // (x+q)^2, q in params.nd
00075 #define EXPRINFO_SQROOT        -13      // sqrt(x+c) c in params.nd
00076 #define EXPRINFO_ABS           -14      // abs(x+c) c in params.nd
00077 #define EXPRINFO_INTPOWER      -15      // x^n (n const. in params.nn)
00078 #define EXPRINFO_EXP           -16      // exp(x+p) p in params.nd
00079 #define EXPRINFO_LOG           -17      // log(x+p) p in params.nd
00080 #define EXPRINFO_SIN           -18      // sin(x + th) th in params.nd
00081 #define EXPRINFO_COS           -19      // cos(x + th) th in params.nd
00082 #define EXPRINFO_GAUSS         -20      // exp(-(x-m)^2/s^2) m, s in params.d
00083 #define EXPRINFO_POLY          -21      // a_0+a_1 x+...+a_n x^n, a in params.d
00084 
00085 // two dimensional
00086 #define EXPRINFO_POW           -22      // (x+p)^y, p in params.nd
00087 #define EXPRINFO_DIV           -23      // a*x/y, a in params.nd
00088 #define EXPRINFO_ATAN2         -24      // atan(x,y) no params
00089 
00090 // these must have variable nodes as children
00091 #define EXPRINFO_LIN           -25      // number of row in lin in params.nn
00092 #define EXPRINFO_QUAD          -26      // (A|b) cont. in params.m x^T A x+b^T x
00093                                         // A is assumed symmetric
00094 
00095 // the following have complex arguments and real results
00096 #define EXPRINFO_RE            -27      // no params
00097 #define EXPRINFO_IM            -28      // no params
00098 #define EXPRINFO_ARG           -29      // no params
00099 
00100 // these have complex arguments and complex results
00101 #define EXPRINFO_CPLXCONJ      -30      // no params
00102 
00103 // these are table driven
00104 #define EXPRINFO_LOOKUP        -31      // table in params.m
00105 #define EXPRINFO_PWLIN         -32      // table in params.m
00106 #define EXPRINFO_SPLINE        -33      // table in params.m
00107 #define EXPRINFO_PWCONSTLC     -34      // table in params.m
00108 #define EXPRINFO_PWCONSTRC     -35      // table in params.m
00109 
00110 // these have discrete results
00111 #define EXPRINFO_IN            -36      // box in params.i
00112 #define EXPRINFO_IF            -37      // truth-interval in params.ni
00113 #define EXPRINFO_AND           -38      // truth-intervals in params.i
00114 #define EXPRINFO_OR            -39      // truth-intervals in params.i
00115 #define EXPRINFO_NOT           -40      // truth-interval in params.ni
00116 #define EXPRINFO_IMPLIES       -41      // truth-intervals in params.i
00117 #define EXPRINFO_COUNT         -42      // truth-intervals in params.i
00118 #define EXPRINFO_ALLDIFF       -43      // max of abs(x_i-x_j) in params.nd
00119 #define EXPRINFO_HISTOGRAM     -44      // pairs of intervals in params.i
00120 #define EXPRINFO_LEVEL         -45      // boxes in params.mi (multi-in)
00121 
00122 // these have discrete arguments and discrete results
00123 #define EXPRINFO_NEIGHBOR      -46      // list of pairs in double long params.n
00124 #define EXPRINFO_NOGOOD        -47      // vector x_0 in params.n
00125 
00126 // the following involve integration
00127 #define EXPRINFO_EXPECTATION   -48      // no params
00128 #define EXPRINFO_INTEGRAL      -49      // integration area in params.i
00129 
00130 // the following highly complex operations implicitly build matrices
00131 // all use params.nm to hold the parameters. Special is params.nm[0],
00132 // because it contains the noted info. If the matrix is sparse, the remaining
00133 // rows contain column index information
00134 #define EXPRINFO_DET           -50      // [0]=0(sparse),1(dense), [1]=dim
00135 #define EXPRINFO_COND          -51      // [0]=0(sparse),1(dense), [1],[2]=dim
00136 #define EXPRINFO_PSD           -52      // [0]=0(sparse),1(dense), [1]=dim
00137 #define EXPRINFO_MPROD         -53      // [0]=0(sparse),1(dense), [1],[2]=dim
00138 #define EXPRINFO_FEM           -54      // [0]=0(sparse),1(dense), [1],[2]=dim
00139 
00140 // these contain constant matrices
00141 #define EXPRINFO_CMPROD        -55      // params.m contains A
00142 #define EXPRINFO_CGFEM         -56      // params.m contains A
00143 
00144 // this should be (last entry)-1 
00145 #define EXPRINFO_UNDEFINED     -57
00146 #define EXPRINFO_NUMOFPREDEF   -(EXPRINFO_UNDEFINED)
00147 
00148 #define EXPR_LASTARG            NULL
00149 
00150 // possible types of the expressions
00151 // ex_bound, ex_linear, ex_quadratic, ex_polynomial, and ex_other are
00152 // mutually exclusive
00153 enum { // type flags
00154        ex_bound=1, ex_linear=1<<1, ex_quadratic=1<<2, ex_polynomial=1<<3,
00155        ex_other=1<<4,
00156 
00157        // automatic from Karush-John conditions (for vars. and constr.)
00158        // ex_kj .... only additional vars, constr. from KJ-conditions
00159        // ex_org ... original vars, constr. (both set = none set)
00160        ex_kj=1<<7, ex_org=1<<8,
00161 
00162        // redundant (both set = none set)
00163        ex_redundant=1<<9, ex_notredundant=1<<10,
00164       
00165        // activity 
00166        // both set = none set = all constraints
00167        ex_active_lo=1<<11, ex_inactive_lo=1<<12,
00168        ex_active_hi=1<<13, ex_inactive_hi=1<<14,
00169        ex_active=ex_active_lo|ex_active_hi,
00170        ex_inactive=ex_inactive_lo|ex_inactive_hi,
00171 
00172        // integer
00173        ex_integer=1<<15,
00174 
00175        // forall, exists, stochastic, free
00176        // none set = select all
00177        ex_exists = 1<<16,
00178        ex_forall = 1<<17,
00179        ex_free = 1<<18,
00180        ex_stochastic = 1<<19,
00181        
00182        // convexity flags (known to be!)
00183        ex_convex=1<<20, ex_concave=1<<21,
00184        
00185        // bound flags
00186        ex_inequality=1<<28, ex_equality=1<<29,
00187        ex_leftbound=1<<30, ex_rightbound=1<<31,
00188 
00189        // short cuts
00190        ex_atmlin=ex_bound|ex_linear,                    // at most linear
00191        ex_atmquad=ex_atmlin|ex_quadratic,               // at most quadratic
00192        ex_atmpoly=ex_atmquad|ex_polynomial,             // at most polynomial
00193        ex_nonlin=ex_quadratic|ex_polynomial|ex_other,   // non linear
00194        ex_nonbnd=ex_linear|ex_nonlin,                   // not bounds
00195        ex_any=ex_atmlin|ex_nonlin,                      // any
00196        ex_bothbound=ex_leftbound|ex_rightbound};
00197 
00198 typedef interval rhs_t; // use intervals as right hand sides of constraints.
00199                         // more general sets could be introduced later
00200 typedef std::vector<void*> evaluator_v;
00201 
00202 #include <addinfo.h>
00203 
00204 class expression_node
00205 {
00206 public:
00207   unsigned int node_num;  // node number for indexing
00208 
00209   int operator_type;      // this is a number describing the operation.
00210                           // negative numbers describe standard operations
00211                           // as defined above.
00212                           // the positive numbers describe other operations
00213                           // like elementary functions (exp, pow, sin,...)
00214                           // or more complicated functions like linear or
00215                           // general quadratic terms, user-defined functions,
00216                           // piecewise linear approximations,...
00217 
00218   unsigned int n_parents, n_children;
00219                           // number of parents, children
00220 
00221   std::vector<double> coeffs;  // coefficients of the sub_expressions
00222 
00223   additional_info_u params; // additional expression info
00224 
00225   interval f_bounds;      // bounds on this node
00226   
00227   unsigned short is_var;  // this node represents is_var variables
00228   std::vector<unsigned int> var_idx;  // the variable indices corresponding to this node
00229 
00230   semantics sem;          // additional semantics information like
00231                           // integer (y/n), stochastic (y/n), karush-john (y/n)
00232                           // convexity,...
00233 
00234   variable_indicator v_i; // this node depends on which variables?
00235 
00236   evaluator_v* ev;        // optional evaluators used instead of tree walks
00237                           // NULL means no evaluators, map if some or all
00238                           // are defined. This is for recursive_cached_walk
00239 
00240 private:
00241   void init()
00242   {
00243     is_var = 0;
00244     f_bounds.set(-INFINITY, INFINITY);
00245   }
00246 
00247 public:
00248   // constructors and destructor
00249   expression_node() : node_num(), operator_type(0), n_parents(0),
00250                       n_children(0), coeffs(), params(), var_idx(),
00251                       sem(), v_i(), ev(NULL)
00252     { init(); }
00253 
00254   expression_node(int et, int nn) : node_num(nn), operator_type(et),
00255                                     n_parents(0), n_children(0), coeffs(),
00256                                     params(), var_idx(), sem(), v_i(),
00257                                     ev(NULL)
00258     { init(); }
00259 
00260   expression_node(const expression_node& __x) : node_num(__x.node_num),
00261         operator_type(__x.operator_type), n_parents(__x.n_parents),
00262         n_children(__x.n_children), coeffs(__x.coeffs), params(__x.params),
00263         f_bounds(__x.f_bounds), is_var(__x.is_var), var_idx(__x.var_idx),
00264         sem(__x.sem), v_i(__x.v_i), ev(__x.ev)
00265     { }
00266 
00267   ~expression_node()
00268     {
00269       if(node_num == 0)
00270         return;
00271       if(ev) delete(ev);
00272     }
00273 
00274   // assignment operator
00275   expression_node& operator=(const expression_node& __x)
00276   {
00277     operator_type = __x.operator_type;
00278     node_num = __x.node_num;
00279     v_i = __x.v_i;
00280     coeffs = __x.coeffs;
00281     params = __x.params;
00282     ev = __x.ev;
00283     sem = __x.sem;
00284     var_idx = __x.var_idx;
00285     is_var = __x.is_var;
00286     f_bounds = __x.f_bounds;
00287     return *this;
00288   }
00289 
00290   class parents_compare;
00291   class children_compare;
00292   class parents_compare_eq;
00293   bool operator<(const expression_node& __x) const;
00294 
00295   // other methods
00296 
00297   void merge(const expression_node& __s)
00298   {
00299     f_bounds.intersect(__s.f_bounds);
00300     if(operator_type != EXPRINFO_VARIABLE)
00301     {
00302       is_var += __s.is_var;
00303       var_idx.insert(var_idx.end(), __s.var_idx.begin(), __s.var_idx.end());
00304     }
00305     n_parents += __s.n_parents;
00306     sem.merge(__s.sem);
00307   }
00308   
00309   void set_bounds(interval __i)
00310   {
00311     f_bounds = __i;
00312   }
00313 
00314   void set_bounds(double __d = 0.)
00315   {
00316     f_bounds = interval(__d);
00317   }
00318 
00319   void set_bounds(int __i)
00320   {
00321     set_bounds(__i+0.);
00322   }
00323 
00324   void set_bounds(double lo, double up)
00325   {
00326     f_bounds = interval(lo, up);
00327   }
00328 
00329   void add_is_var(unsigned int idx)
00330   {
00331     is_var++;
00332     var_idx.push_back(idx);
00333   }
00334 
00335   void rm_is_var(unsigned int idx)
00336   {
00337     for(std::vector<unsigned int>::iterator b = var_idx.begin();
00338         b != var_idx.end(); b++)
00339       if(*b == idx)
00340       {
00341         var_idx.erase(b);
00342         is_var--;
00343       }
00344   }
00345 
00346   bool is(unsigned int __tp) const;
00347     
00348   // and others needed
00349   // print the expression_node
00350   friend std::ostream& operator<< (std::ostream& o, const expression_node& __x);
00351 
00352   // construct C expression
00353   friend std::string& print_C_pre(std::string& __s, const expression_node& __x);
00354   friend std::string& print_C_post(std::string& __s, const expression_node& __x);
00355 
00356   // and others needed
00357   const variable_indicator& var_indicator() const { return v_i; }
00358 
00359   // extra evaluation routines
00360   double f_evaluate(int argnum, int idx, const std::vector<double> &x, const variable_indicator& v_i, double fold, double fupd, std::vector<double> *cache_data) const { return 0; }
00361   interval i_evaluate(int argnum, int idx, const std::vector<interval> &x, const variable_indicator& v_i, interval fold, interval fupd, std::vector<interval> *cache_data) const { return interval(); }
00362   interval cp_evaluate(int argnum, int idx, const std::vector<interval> &node_range, const variable_indicator& v_i, interval fold, interval fupd, std::vector<interval> *cache_data) const { return interval(); }
00363 public:
00364 };
00365 
00366 // include implementation of the huge methods
00367 #include <expr-inline.h>
00368 
00369 #endif // _EXPRESSION_H_

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