[GiNaC-list] Defining a new symbol class (mysymbol.cpp)

jros jros at unavarra.es
Tue Nov 13 14:30:21 CET 2007


Hello :) !

After a year using GiNaC, we are thinking now that using classes
can improve a lot our programming efforts.

I think this is my n-th atempt to define a new class, but I'm having
(again) some troubles. 

I've proposed to derive a new class that represents a new type of
symbol, for example a symbol that has a special derivative 
(just as an example assume we want to get something like

mysymbol e("e");
symbol c("c");
cout<<diff(e,e)<<endl;
//->2

I know it is not very logical).

I want to derive from symbol.

But if I follow mystring.cpp example, and I try to change

GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(mystring, basic,
  print_func<print_context>(&mystring::do_print))

to

GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(mystring, symbol,
  print_func<print_context>(&mystring::do_print))

(analogously with GINAC_IMPLEMENT_REGISTERED_CLASS_OPT)

just to see if it compiles, with 1.4 or 1.3.6...

But no success.

Second and last atempt has been to look for a descendant of symbol in
GiNaC code.

I've taken realsymbol as an starting point. The code is copy/pasted at
the end. And it compiles and executes.

The question is, OK it works, but the strategy to derive such a class
is not related to the one of the mystring.cpp tutorial.

So we do not know why it works, and if teh strategy we are usin to
derive is correct.

What is the logic?; Is mystring tutorial only valid when deriving from
basic?.

The code is just a copy paste of symbol.cpp symbol.h sections related to
realsymbol, I rename realsymbol to mysymbol.

Nevertheless we dont achieve to output the desired derivarive, buit a
logical one, the method

mysymbol::derivative

Is not called, and we don't know why?. Should we use a new type of ex
also?. Perhaps this is a C++ question but I'm not sure right now,...
(sorry if this is the case)

Is there a documented example appart from mystring.cpp at the tutorial?.


We are workin wit 1.4 GiNaC version.

Thanks in advance


Javier Ros



mysymbol.cpp listing
-------------------------------------------------------------------------------
/** Specialization of symbol to suit my own needs */

#include <iostream>
#include <string>   
#include <stdexcept>
using namespace std;

#include <ginac/ginac.h>
using namespace GiNaC;

namespace GiNaC {

class mysymbol : public symbol
{
	// constructors
public:
	mysymbol();
	explicit mysymbol(const std::string & initname, unsigned domain =
domain::real);
	mysymbol(const std::string & initname, const std::string & texname,
unsigned domain = domain::real);
	mysymbol(const std::string & initname, unsigned rt, tinfo_t rtt,
unsigned domain = domain::real);
	mysymbol(const std::string & initname, const std::string & texname,
unsigned rt, tinfo_t rtt, unsigned domain = domain::real);

protected:
	ex derivative(const symbol & s) const;
	int compare_same_type(const basic & other) const;
};

// mysymbol

mysymbol::mysymbol()
{
	domain = domain::real;
}

// mysymbol
	
mysymbol::mysymbol(const std::string & initname, unsigned domain)
 : symbol(initname, domain) { }

mysymbol::mysymbol(const std::string & initname, const std::string &
texname, unsigned domain)
 : symbol(initname, texname, domain) { }

mysymbol::mysymbol(const std::string & initname, unsigned rt, tinfo_t
rtt, unsigned domain)
 : symbol(initname, rt, rtt, domain) { }

mysymbol::mysymbol(const std::string & initname, const std::string &
texname, unsigned rt, tinfo_t rtt, unsigned domain)
 : symbol(initname, texname, rt, rtt, domain) { }

}

ex mysymbol::derivative(const symbol & s) const
{
	cout << "Here I'm\n";

	if (compare_same_type(s))
		return 0;
	else
		return 2;
}

int mysymbol::compare_same_type(const basic & other) const
{

	GINAC_ASSERT(is_a<mysymbol>(other));
	const mysymbol *o = static_cast<const mysymbol *>(&other);
	if (serial==o->serial) return 0;
	return serial < o->serial ? -1 : 1;
}

int main(int argc, char** argv)
{
	symbol a("a"), b("b"), c("c"); 
	mysymbol e("e1");
	cout << diff((e*(a+e*(b+c*e)) - (a*e+b*e*e)).expand(),e) << endl;
	cout << diff((e*(a+e*(b+c*e)) - (a*e+b*e*e)).expand(),c) << endl;
	return 0;
}





More information about the GiNaC-list mailing list