Qucs-core  0.0.19
equation.h
Go to the documentation of this file.
00001 /*
00002  * equation.h - checker definitions for Qucs equations
00003  *
00004  * Copyright (C) 2004-2009 Stefan Jahn <stefan@lkcc.org>
00005  *
00006  * This 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, or (at your option)
00009  * any later version.
00010  *
00011  * This software 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 package; see the file COPYING.  If not, write to
00018  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020  *
00021  * $Id$
00022  *
00023  */
00024 
00025 #ifndef __EQUATION_H__
00026 #define __EQUATION_H__
00027 
00028 #include "object.h"
00029 #include "complex.h"
00030 #include "vector.h"
00031 #include "matrix.h"
00032 #include "matvec.h"
00033 
00034 struct definition_t;
00035 
00036 namespace qucs {
00037 
00038 class strlist;
00039 class dataset;
00040 class range;
00041 
00042 namespace eqn {
00043 
00044 class solver;
00045 class checker;
00046 class constant;
00047 class reference;
00048 class assignment;
00049 class application;
00050 
00051 enum NodeTag {
00052   UNKNOWN = -1,
00053   CONSTANT = 0, /* source code constant */
00054   REFERENCE,    /* variable reference   */
00055   APPLICATION,  /* call to function     */
00056   ASSIGNMENT    /* root of equation     */
00057 };
00058 
00059 /* The equation node base class defines and implements the basic
00060    functionality of an equation node.  Possible types of nodes are
00061    listed in 'NodeTag'. */
00062 class node
00063 {
00064 public:
00065   node ();
00066   node (int);
00067   node (const node &);
00068   virtual ~node ();
00069   node * getNext (void) { return next; }
00070   void setNext (node * n) { next = n; }
00071   int count (void);
00072   void append (node *);
00073   void appendNodes (node *);
00074   void setDependencies (strlist *);
00075   strlist * getDependencies (void);
00076   void setDataDependencies (strlist *);
00077   strlist * getDataDependencies (void) { return dataDependencies; }
00078   void setDropDependencies (strlist * deps) { dropDependencies = deps; }
00079   void addDropDependencies (char *);
00080   strlist * getDropDependencies (void) { return dropDependencies; }
00081   void setPrepDependencies (strlist * deps) { prepDependencies = deps; }
00082   void addPrepDependencies (char *);
00083   void appendPrepDependencies (strlist *);
00084   strlist * getPrepDependencies (void) { return prepDependencies; }
00085   strlist * recurseDependencies (checker *, strlist *);
00086   node * get (int);
00087   constant * getResult (int);
00088   int getType (void) { return type; }
00089   int getTag (void) { return tag; }
00090   void setType (int tag) { type = tag; }
00091   constant * getResult (void) { return res; }
00092   nr_double_t getResultDouble (void);
00093   nr_complex_t getResultComplex (void);
00094   qucs::vector getResultVector (void);
00095   void setResult (constant *);
00096   char * getInstance (void);
00097   void setInstance (const char *);
00098   void applyInstance (void);
00099   constant * calculate (void);
00100   strlist * collectDependencies (void);
00101   strlist * collectDataDependencies (void);
00102 
00103   /* These functions should be overloaded by derivative classes. */
00104   virtual void print (void) { }
00105   virtual void addDependencies (strlist *) { }
00106   virtual int evalType (void) { return type; }
00107   virtual char * toString (void) { return txt; }
00108   virtual constant * evaluate (void) { return res; }
00109   virtual node * differentiate (char *) { return this; }
00110   virtual node * recreate (void) { return new node (*this); }
00111   virtual void replace (char *, char *) { }
00112 
00113 public:
00114   int duplicate;
00115   int cycle;
00116   int evalPossible;
00117   int skip;
00118   char * txt;
00119   int evaluated;
00120   char * instance;
00121   int output;
00122   int dropdeps;
00123   solver * solvee;
00124   checker * checkee;
00125 
00126 private:
00127   int type;
00128   int tag;
00129   node * next;
00130   strlist * dependencies;
00131   constant * res;
00132   strlist * dataDependencies;
00133   strlist * dropDependencies;
00134   strlist * prepDependencies;
00135 };
00136 
00137 enum ConstantTag {
00138   TAG_UNKNOWN =   0,
00139   TAG_DOUBLE  =   1, /* double constant          */
00140   TAG_COMPLEX =   2, /* complex value            */
00141   TAG_VECTOR  =   4, /* list of complex values   */
00142   TAG_MATRIX  =   8, /* complex matrix           */
00143   TAG_MATVEC  =  16, /* list of complex matrices */
00144   TAG_CHAR    =  32, /* single character         */
00145   TAG_STRING  =  64, /* character string         */
00146   TAG_RANGE   = 128, /* interval specification   */
00147   TAG_BOOLEAN = 256, /* boolean value            */
00148 };
00149 
00150 /* This class represents any type of constant expression. */
00151 class constant : public node
00152 {
00153 public:
00154   constant ();
00155   constant (int);
00156   constant (const constant &);
00157   ~constant ();
00158   void print (void);
00159   int evalType (void);
00160   char * toString (void);
00161   constant * evaluate (void);
00162   node * differentiate (char *);
00163   node * recreate (void);
00164 
00165 public:
00166   bool dataref;
00167   int type;
00168   union {
00169     nr_double_t d;
00170     nr_complex_t * c;
00171     qucs::vector * v;
00172     matrix * m;
00173     matvec * mv;
00174     char chr;
00175     char * s;
00176     range * r;
00177     bool b;
00178   };
00179 };
00180 
00181 /* The class represents variable references. */
00182 class reference : public node
00183 {
00184 public:
00185   reference ();
00186   reference (const reference &);
00187   ~reference ();
00188   void print (void);
00189   void addDependencies (strlist *);
00190   void findVariable (void);
00191   int evalType (void);
00192   char * toString (void);
00193   constant * evaluate (void);
00194   node * differentiate (char *);
00195   node * recreate (void);
00196   void replace (char *, char *);
00197 
00198 public:
00199   char * n;
00200   node * ref;
00201 };
00202 
00203 /* This class represents assignments with a left hand and right hand
00204    side. */
00205 class assignment : public node
00206 {
00207 public:
00208   assignment ();
00209   assignment (const assignment &);
00210   ~assignment ();
00211   void print (void);
00212   void addDependencies (strlist *);
00213   int evalType (void);
00214   char * toString (void);
00215   constant * evaluate (void);
00216   node * differentiate (char *);
00217   node * recreate (void);
00218   void replace (char *, char *);
00219   void rename (char *);
00220   void mul (assignment *);
00221   void add (assignment *);
00222   void mulref (assignment *);
00223 
00224 public:
00225   char * result;
00226   node * body;
00227 };
00228 
00229 // Type of application function.
00230 typedef constant * (* evaluator_t) (constant *);
00231 
00232 // Type of derivative function.
00233 typedef node * (* differentiator_t) (application *, char *);
00234 
00235 /* The application class represents any kind of operation (unary,
00236    binary and n-ary ones) containing the appropriate argument list. */
00237 class application : public node
00238 {
00239 public:
00240   application ();
00241   application (const application &);
00242   application (const char *, int);
00243   ~application ();
00244   void print (void);
00245   void addDependencies (strlist *);
00246   int evalType (void);
00247   char * toString (void);
00248   constant * evaluate (void);
00249   node * differentiate (char *);
00250   node * recreate (void);
00251   void replace (char *, char *);
00252 
00253 public:
00254   char * n;
00255   int nargs;
00256   node * args;
00257   node * ddx;
00258   evaluator_t eval;
00259   differentiator_t derive;
00260 
00261 private:
00262   void evalTypeArgs (void);
00263   char * createKey (void);
00264   int evalTypeFast (void);
00265   int findDifferentiator (void);
00266 };
00267 
00268 /* This class implements the actual functionality regarding a set of
00269    equations stored within a netlist. */
00270 class checker
00271 {
00272 public:
00273   checker ();
00274   ~checker ();
00275   void collectDependencies (void);
00276   void collectDependencies (node *);
00277   void setEquations (node *);
00278   node * getEquations (void) { return equations; }
00279   void list (void);
00280   int findUndefined (int);
00281   static const char * tag2key (int);
00282   static int isGenerated (char *);
00283   strlist * getVariables (void);
00284   int findDuplicate (void);
00285   static node * findEquation (node *, const char * const);
00286   int detectCycles (void);
00287   static strlist * foldDependencies (strlist *);
00288   node * appendEquation (node *, node *);
00289   void dropEquation (node *);
00290   void reorderEquations (void);
00291   static node * lastEquation (node *);
00292   int applyTypes (void);
00293   int checkExport (void);
00294   void constants (void);
00295   int check (int noundefined = 1);
00296   strlist * variables (void);
00297   node * addDouble (const char *, const char *, nr_double_t);
00298   node * createDouble (const char *, const char *, nr_double_t);
00299   node * addComplex (const char *, const char *, nr_complex_t);
00300   node * createComplex (const char *, const char *, nr_complex_t);
00301   node * addReference (const char *, const char *, char *);
00302   node * createReference (const char *, const char *, char *);
00303   void appendEquation (node *);
00304   void addEquation (node *);
00305   node * findEquation (const char *
00306                        const) const;
00307   bool containsVariable (const char * const) const;
00308   nr_double_t getDouble (const char *const) const;
00309   void setDouble (const char *const, nr_double_t);
00310   qucs::vector getVector (const char * const) const;
00311   void setDefinitions (struct definition_t * d) { defs = d; }
00312   struct definition_t * getDefinitions (void) { return defs; }
00313   node * findProperty (char *);
00314 
00315 public:
00316   node * equations;
00317 
00318  private:
00319   bool consts;
00320   struct definition_t * defs;
00321 };
00322 
00323 /* The solver class is finally used to solve the list of equations. */
00324 class solver
00325 {
00326 public:
00327   solver (checker *);
00328   ~solver ();
00329   void setEquations (node * eqn) { equations = eqn; }
00330   node * getEquations (void) { return equations; }
00331   void setData (dataset * d) { data = d; }
00332   dataset * getDataset (void) { return data; }
00333   void evaluate (void);
00334   node * addEquationData (qucs::vector *, bool ref = false);
00335   node * addEquationData (matvec *);
00336   node * addGeneratedEquation (qucs::vector *, const char *);
00337   qucs::vector * dataVector (node *);
00338   void checkinDataset (void);
00339   void checkoutDataset (void);
00340   static int dataSize (constant *);
00341   int getDependencySize (strlist *, int);
00342   int getDataSize (char *);
00343   strlist * collectDataDependencies (node *);
00344   int dataSize (strlist *);
00345   qucs::vector * getDataVector (char *);
00346   void findMatrixVectors (qucs::vector *);
00347   char * isMatrixVector (char *, int&, int&);
00348   int findEquationResult (node *);
00349   int solve (dataset *);
00350 
00351 public:
00352   node * equations;
00353 
00354 private:
00355   dataset * data;
00356   int generated;
00357   checker * checkee;
00358 };
00359 
00360 } /* namespace eqn */
00361 
00362 } // namespace qucs
00363 
00364 #endif /* __EQUATION_H__ */