small GiNaC query
Sheplyakov Alexei
varg at thsun1.jinr.ru
Tue Jan 27 20:39:38 CET 2004
On Tue, Jan 27, 2004 at 04:41:05PM -0000, keith.briggs at 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;
}
-------------- next part --------------
#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;
}
More information about the GiNaC-list
mailing list