Qucs-core
0.0.19
|
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__ */