[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