/* map.h -
This file is part of Kalamaris
Copyright (C) 2000 Antonio Larrosa Jimenez
Kalamaris' homepage : http://www.arrakis.es/~rlarrosa/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 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 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);
public:
/**
* Textual definition . "2*x+3"
*/
QString def;
/**
* Name of this function . "cos"
*/
QString name;
unsigned int nparams;
QStringList *paramlist;
class Parameter **params;
/**
* 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 *tree;
static QDict <Map>maps;
/**
* 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);
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 ) { forceevaluation=b; };
inline int forceEvaluation( void ) const { return forceevaluation; };
virtual void propagateForceEvaluation( bool b=true );
virtual Map *copy(void);
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());
void debugMaps(const QDict <Map>&vars);
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 mapName(void) const { return name; };
QString isA(void) { return isAClassName; };
int isA(QString s) const { return 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 int isConstant(void) const { return isA("Constant"); };
virtual inline bool isInternal(void) const { return false; };
static int 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
*/
inline void setTree(Map *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
*/
int nArgs(void) const { return nparams; };
/**
* Returns the map used as i-th argument.
*/
Map *argument(unsigned int i) const;
/**
* Returns the parameter used as i-th argument.
*/
inline Parameter *parameter(unsigned int i) const { return (i<nparams)?params[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;
};
//Map *operator +(const Map &m1, const Map &m2);
#endif
| Generated by: antlarr@terminus on Wed May 31 08:19:51 2000, using kdoc 2.0a22. |