[GiNaC-list] "Internal error..." report -- probably misused map.
Warren Weckesser
WWeckesser at mail.colgate.edu
Thu Aug 10 08:56:54 CEST 2006
Hi,
I am working on a program that generates code for other libraries
or programs. One of the target libraries is CVODE, a solver for
differential equations (part of the SUNDIALS suite).
In CVODE, numbers are represented with a typedef 'realtype', which
can be chosen to be float, double, or one or two other options.
To ensure consistent use of realtype, constants are wrapped in the
macro RCONST. I am trying to automate this in ginac. I am using
ginac version 1.3.4 (compiled with gcc 4.0.2 on Ubuntu Linux).
In some of my first attempts to do this, I occasionally got an
"internal error" message. The following code is a simplified
version that causes the error:
--- ginacwrap1.cpp --------------------------------------------
#include <iostream>
#include <ginac/ginac.h>
using namespace std;
using namespace GiNaC;
DECLARE_FUNCTION_1P(RCONST)
REGISTER_FUNCTION(RCONST,dummy())
ex wrap1(const ex & e)
{
if (is_a<numeric>(e))
return RCONST(e);
else
return e.map(wrap1);
}
int main(void)
{
symbol x("x");
ex p = cos(1+x); // Internal error: ... line 93 has been reached!
// ex p = 2*x; // Internal error: ... line 30 has been reached!
// ex p = 2+sin(2); // Works: wrap1(p) = RCONST(2)+sin(RCONST(2))
ex w = wrap1(p);
cout << "wrap1(p) = " << w << endl;
}
---------------------------------------------------------------
This results in an "internal error":
Internal error: statement in file ./real/elem/cl_R_mul.cc, line 93 has been reached!!
Please send the authors of the program a description how you produced this error!
If the expression p is changed to 2*x (see the comments), a similar
internal error is reported.
After more work, I ended up with the code shown below, which seems to
do what I want (but any suggestions for a better method would be
appreciated). I had to define my own print function for the RCONST
function, because the default print function converted the name to
lower case when csrc was used. One remaining nuisance: In csrc mode,
ginac prints the expression -x as "-1.0*x". Is there a way to have it
output "-x" in csrc mode?
Best regards,
Warren Weckesser
--- ginacwrap2.cpp --------------------------------------------
#include <iostream>
#include <ginac/ginac.h>
using namespace std;
using namespace GiNaC;
static void RCONST_print_csrc_double(const ex & arg, const print_context & c)
{
c.s << "RCONST(";
arg.print(c);
c.s << ")";
}
DECLARE_FUNCTION_1P(RCONST)
REGISTER_FUNCTION(RCONST,print_func<print_csrc_double>(RCONST_print_csrc_double))
ex wrap2(const ex& e)
{
if (is_a<numeric>(e))
return RCONST(e);
if (is_a<symbol>(e))
return e;
if (is_a<add>(e))
{
ex s = 0;
for (size_t k = 0; k < e.nops(); ++k)
s = s + wrap2(e.op(k));
return s;
}
if (is_a<mul>(e))
{
ex p = 1;
for (size_t k = 0; k < e.nops(); ++k)
p = p * wrap2(e.op(k));
return p;
}
return e.map(wrap2);
}
int main(void)
{
symbol x("x");
cout << csrc;
ex p = -exp(-x)+x*x;
cout << "p = " << p << endl;
ex w = wrap2(p);
cout << "wrap2(p) = " << w << endl;
}
----------------------------------------------------------------
More information about the GiNaC-list
mailing list