|
|
/* map.h - This file is part of Kalamaris Copyright (C) 2000 Antonio Larrosa Jimenez Kalamaris' homepage : http://perso.wanadoo.es/antlarr/kalamaris.html This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Send comments and bug fixes to Antonio Larrosa <larrosa@kde.org> ***************************************************************************/ #ifndef _MAP_H #define _MAP_H #include <qstring.h> #include <qdict.h> #include <qstringlist.h> #include "vartype.h" #include "tmatrix.h" //#define T double /** * The basic element. Map can be anything (by inheriting it), but it's nearly * nothing by default. * * A Map object just has a pointer to another Map object, and when you * make it do anything, it passes the command to the next Map object. * * @short A basic map, which every other element in Kalamaris inherits. * @version 0.5.2 30/05/2000 * @author Antonio Larrosa Jimenez <larrosa@kde.org> */ class Map { protected: QString m_isAClassName; /** * Sometimes, we want to evaluate some maps and some not, so we set the * $$__noEvaluateFunctions flag, and set forceevaluation on maps we want * to evaluate */ bool m_forceEvaluation; /** * Splits a string in several strings, separated by sep. The difference * with QStringList::split, is that this method takes care of (basic) * syntaxis, not to break things like : f(x,y,g(a,b)) in * (x , y , g(a , b)) instead of (x, y, g(a,b) ) */ QStringList split(const QChar &sep, const QString &str); /** * Textual definition . "2*x+3" */ QString m_definition; /** * Name of this function . "cos" */ QString m_name; unsigned int m_nParameters; QStringList *m_parameterList; class Parameter **m_parameters; /** * The expression at the parameters . For example, if this function * was defined as "f(x)=3+x" then "tree" contains : * f * | * + * / \ * 3 x * * But let's suppose f is being used on the definition of a g function * like this : "g(x)=4*f(2*x)" . In this case, paramexpr contains * * * / \ * 2 x * * When evaluating f, paramexpr will be evaluated first, and their values * will be assigned to the "params" variables. * * g's tree will contain : * * * / \ paramexpr * 4 f ------>x= * | | * + * * / \ / \ * 3 x 2 x * */ Map *m_tree; public: static QDict <Map>maps; protected: /** * Check each parameter to see if they have correct data types. * Returns true if everything is ok, false if it's not. */ int checkParamTypes(const QDict <Map> &vars) const; Map (const QString &nam,int); public: Map (const QString &decl=QString(), const QStringList ¶ms=QStringList(), const QString &nam=QString(), bool parsedefinition=true); Map (const Map &m); virtual ~Map(); void setName(const QString &nam,bool insertInDict=true); inline void setForceEvaluation( bool b=false ) { m_forceEvaluation=b; }; inline int forceEvaluation( void ) const { return m_forceEvaluation; }; virtual void propagateForceEvaluation( bool b=true ); virtual Map *copy(void) const; virtual void setParameterExpression(unsigned int i,const QString &expr); virtual void setParameterExpression(unsigned int i, Map *expr); virtual void setParameterExpression(unsigned int i, Parameter *expr); /** * Parses the parameters and call setParameterExpression automatically * The parameter should be in the form "14,x+2" for a call in the * form f(14,x+2) */ void setParameters(const QString ¶ms); /** * Set the parameters by copying them from Map "from". */ // void setParameters(const Map &from); /** * Evaluates the parameters and stores them in a new QDict object. * For example, if the function is f(x,z) and is used as this : * 2*f(3*x,y+1), and vars contains { x=5, y=6 }, then the QDict object * this function returns contains { x=15, y=6, z=7 }. * * Note that you must delete the pointer that this function returns * after using it ! */ QDict <Map> *evalParams(const QDict <Map> &vars); virtual Map *eval(const QDict <Map> &vars); /** * Derivates (symbolically) the current map with respect to the variable var. */ virtual Map *derive(const class Variable &var, const QDict <Map> &vars); /** * Searches in the pool of maps for one with name "name", constructs a * new map object of the same type and returns it */ static Map *functionFactory(const QString &name); /** * Parses a string and creates a map object. */ static Map *parse(QString def); void printDebug(const QString &tab=QString()) const; void debugMaps(const QDict <Map>&vars) const; virtual QString string(void) const; virtual QString htmlString(void) const; static QString helpPrefix(void); virtual QString help(void) const; static QString helpPostfix(void); inline QString name(void) const { return m_name; }; QString isA(void) const { return m_isAClassName; }; bool isA(QString s) const { return m_isAClassName==s; }; /** * Returns true if this map doesn't depend on any variable. * The difference with isA("Constant") is that this also check * (when implemented) for constant matrices. */ virtual bool isConstant(void) const { return isA("Constant"); }; virtual inline bool isInternal(void) const { return false; }; static bool isInternal(const QString &name); /** * Returns a simplified form of this Map if possible. * If there's no simplified form, it returns 0L . */ virtual Map *simplify(); /** * Simplifies the tree calling simplify and substituting it with * the simplified form. Note that it's "not desirable" to call this * method on non-Map classes. */ void simplifyFunction(); /** * Sets the tree . Use with extreme care ! * * *inline void setTree(Map *m) { m_tree=m; }; */ /** * Binary operations for maps. The nice thing about these methods is that * they are quite optimized to do always the best thing with the pointers. * For example, when you sum two temporary maps (and tell Map::add to * "manage" them), they're not copied, but used directly. * * With managem1 and managem2, you specify that you aren't going to need * that pointer anymore, so instead of deleting it yourself in the next * line, you tell Map::add to do whatever it wants with it, so if it isn't * going to be used, it will be deleted. If you use true as value for * managem1 or managem2, be sure to not reference that variable anymore, as * it may be deleted ! (in this case, it will be set to 0L). */ static Map *add(Map * &m1, Map * &m2, bool managem1=false, bool managem2=false); static Map *sub(Map * &m1, Map * &m2, bool managem1=false, bool managem2=false); static Map *mul(Map * &m1, Map * &m2, bool managem1=false, bool managem2=false); static Map *div(Map * &m1, Map * &m2, bool managem1=false, bool managem2=false); static Map *pow(Map * &m1, Map * &m2, bool managem1=false, bool managem2=false); /** * These functions are provided for convience and should be used with * extreme care */ static Map *add2(Map * m1, Map * m2, bool managem1=false, bool managem2=false); static Map *sub2(Map * m1, Map * m2, bool managem1=false, bool managem2=false); static Map *mul2(Map * m1, Map * m2, bool managem1=false, bool managem2=false); static Map *div2(Map * m1, Map * m2, bool managem1=false, bool managem2=false); static Map *pow2(Map * m1, Map * m2, bool managem1=false, bool managem2=false); /** * Returns the number of arguments */ unsigned int nArgs(void) const { return m_nParameters; }; /** * Returns the map used as i-th argument. */ Map *argument(unsigned int i) const; /** * Returns the parameter at the i-th position. */ inline Parameter *parameter(unsigned int i) const { return (i < m_nParameters) ? m_parameters[i] : 0L; }; /** * Returns a T object if this is a Constant Map. else, it returns 0L * It's not neccesary to check if this->isA("Constant") since it's a virtual * method. */ virtual inline T *t(void) const { return 0L; }; /** * Returns a TMatrix object if this is a Matrix Map. else, it returns 0L * It's not neccesary to check if this->isA("Matrix") since it's a virtual * method. */ virtual inline TMatrix *tmatrix(void) const { return 0L; }; // operator const T_TYPE () const; }; #endif
Generated by: antonio@tazend on Fri May 25 22:16:00 2001, using kdoc 2.0a38. |