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