On Tue, Jan 27, 2004 at 04:41:05PM -0000, keith.briggs@bt.com wrote:
How do I get the program below to compute 1/6*s.1^3+1/2*s.1*s.2+1/3*s.3 ? I don't care about ordering of summands, but I need the s.1*s.2 and s.2*s.1 terms to be merged and s.1*s.1*s.1 to be converted to s.1^3.
Looks like you have different symbols with same printable form...
ex Z(int n) { if (n==0) return 1; ex r=0; symbol s("s"),i_sym("i"); idx i(i_sym,n); for (int j=1; j<=n; j++) { ex si=indexed(s,i); r+=si.subs(i==j)*Z(n-j);
... yes, you really do. Every time you call function Z, new symbol with printable form "s" constructed. That's probably not what you want to do. You might try this: #include <iostream> #include <map> #include <string> #include <sstream> #include <vector> #include <algorithm> #include <functional> #include <stdexcept> using namespace std; #include <ginac/ginac.h> using namespace GiNaC; // Shamelessly ripped from GiNaC FAQ :) const symbol symbol_factory(const int & i_ ) { static map<int, symbol> directory; map<int, symbol>::iterator i = directory.find(i_); if (i!=directory.end()) return i->second; ostringstream so ; so << "s" << i_; string s = so.str(); return directory.insert(map<int, symbol>::value_type(i_, symbol(s))).first->second; } // I'm not sure if you really need indexed things... ex Z (const int & n) { if ( n == 0 ) return ex(1); ex result(0); for (int j = 1; j <= n; j++ ) result += (symbol_factory(j)*Z(n-j)).expand(); return result; } int main(int argc, char** argv) { int arg = 3; if(argc >= 2) arg = atoi(argv[1]); cout << "Z(" << arg << ") = " << Z(arg) << endl; return 0; }