[GiNaC-devel] Custom power evaluation

Vladimir Kisil kisilv at maths.leeds.ac.uk
Sun Oct 22 13:55:16 CEST 2006


		Dear All,

		In my GiNaC code I oftenly use some objects which have special
  properties with respect to power. For example, if values of a symbol s
  are assumed to be only -1, 0, or 1, then s^3=s. Another example is
  provided by "imaginary units" for double and dual numbers.

  It will be good for such objects to use such simplifying identities on the
  fly in power_eval() method rather then by user calls to subs()
  afterwards. I propose a patch to GiNaC which allows to supply such
  simplification rules from a user-defined classes. It requires only two
  new virtual methods to basic class and should not involve much
  overheads to the general GiNaC performance.

  I give an example below (which should work with the patch) for a
  symbol which is assumed to take only values -1 or 1, thus satisfying to
  s^2=1 rule.

  If general feeling toward this proposition will be positive I would
  send a more complete patch including documentation.

  Best wishes,
  Vladimir

  PS Somehow I was not able to use macros DEFAULT_UNARCHIVE() and
  DEFAULT_COMPARE() for my class, since compiler produces the error:

  error: expected constructor, destructor, or type conversion before
  'int'

  What may be the reason for this?
-- 
Vladimir V. Kisil     email: kisilv at maths.leeds.ac.uk
--                      www: http://maths.leeds.ac.uk/~kisilv/

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

class myrealsymb : public symbol
{
GINAC_DECLARE_REGISTERED_CLASS(myrealsymb, symbol)

public:
	myrealsymb(const std::string & initname);
	virtual ex eval_power_basis(const ex & exp) const;
	virtual bool info(unsigned inf) const;
};

GINAC_IMPLEMENT_REGISTERED_CLASS(myrealsymb,symbol)

myrealsymb::myrealsymb(): symbol(){};

myrealsymb::myrealsymb(const std::string & initname) : symbol(initname) {;}

ex myrealsymb::eval_power_basis(const ex & exp) const
{
	if (is_a<numeric>(exp)) {
		if (ex_to<numeric>(exp).is_even())
			return numeric(1);
		if (ex_to<numeric>(exp).is_odd())
			return *this;
	}
	return power(*this,exp).hold(); 
}

bool myrealsymb::info(unsigned inf) const
{
	return (inf == info_flags::is_power_basis) || symbol::info(inf);
}


myrealsymb::myrealsymb(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
{
}

void myrealsymb::archive(archive_node &n) const
{
	symbol::archive(n);
}

ex myrealsymb::unarchive(const archive_node &n, lst &sym_lst) 
{ 
	return (new myrealsymb(n, sym_lst))->symbol::setflag(status_flags::dynallocated); 
}


int myrealsymb::compare_same_type(const basic & other) const
{
	return symbol::compare_same_type(other);
}

int main(){
	try {
		ex e=myrealsymb("s");
		cout << pow(e,2) << endl; 
		// -> 1
		cout << pow(1+e,2).expand() << endl;
		// -> 2+2*s
	} catch  (exception &p) {
		cerr << "Got problem: " <<  p.what() << endl;
	}
	return 0;
}

-------------- next part --------------
A non-text attachment was scrubbed...
Name: ginac.diff
Type: text/x-c++
Size: 3175 bytes
Desc: GiNaC patch
URL: <http://www.ginac.de/pipermail/ginac-devel/attachments/20061022/b14f0cef/attachment.bin>


More information about the GiNaC-devel mailing list