[GiNaC-devel] proposed integration algorithm

Jose Antonio Garcia Peiro jgpeiro at gmail.com
Fri Sep 10 03:26:32 CEST 2010


Hi

I am very interested in GiNaC, but I also need symbolic integration,
and GiNaC only compute basic integrals. I wrote a simple recursive
routine that applies a basic integration rules, matching the input
function.
It is a good way to implement integration algoritm?

Thanks


int(c,x) = c*x
int(x,x) = x^2/2
int(f+g,x) = int(f,x) + int(g,x)
int(c*f,x) = c*int(f,x)
int( f^c*1,x) = f^(c+1)/(c+1) or log(f)
int( f^c*f',x) = f^(c+1)/(c+1) or log(f)

some examples:

cout << "int(1+x,x) = " << myinteg( 1 + x, x ) << endl;
                 // 1/2*x^2+x
cout << "int(3*x^2+x+6,x) = " << myinteg( 3*pow(x,2)+x+6, x ) << endl;
       // 1/2*x^2+x^3+6*x
cout << "int((3*x+5)^2*3,x) = " << myinteg( pow(3*x+5,2)*3, x ) <<
endl;       // 1/3*(5+3*x)^3
cout << "int((3*x+5)^(-1)*3,x) = " << myinteg( pow(3*x+5,-1)*3, x ) <<
endl;   // log(5+3*x)
cout << "int((3*x+5)^b*3,x) = " << myinteg( pow(3*x+5,b)*3, x ) <<
endl;       // (1+b)^(-1)*(5+3*x)^(1+b)


the code (with debug messages):
ex myinteg( const ex &f, const symbol &x ){
	
	exmap repls;

	cout << endl << "f(x) = " << f << endl;
	//int(c,x)		c*x
	if( !has( f, x ) ){
		cout << "match int(c,x)" << endl;
		return f*x;
	}

	//int(x,x)		x^2/2
	if( f.is_equal(x) ){
		cout << "match int(x,x)" << endl;	
		return pow(x,2)/2;
	}	

	//int(f+g,x)	int(f,x)+int(g,x)
	if( f.match( wild(0)+wild(1), repls ) ){
		cout << "match int(f+g,x)" << endl;
		cout << "wild(0)+wild(1) = " << repls << endl;
		ex f, g;
		for( exmap::const_iterator i=repls.begin(); i!=repls.end(); ++i){
			if(i->first.is_equal(wild(0)) ){
				f = i->second;
			}else if(i->first.is_equal(wild(1))){
				g = i->second;
			}
		}
		cout << "f = " << f << endl;
		cout << "g = " << g << endl;
		return myinteg( f, x ) + myinteg( g, x );
	}

	//int(c*f,x)		c*int(f,x)
	if( f.match( wild(0)*wild(1), repls ) ){
		cout << "match int(c*f,x)" << endl;
		cout << "wild(0)*wild(1) = " << repls << endl;
		ex c, f;
		for( exmap::const_iterator i=repls.begin(); i!=repls.end(); ++i){
			if(i->first.is_equal(wild(0)) ){
				c = i->second;
			}else if(i->first.is_equal(wild(1))){
				f = i->second;
			}
		}
		if( !has( c, x ) && has( f, x )){
			return c*myinteg( f, x );
		}if( has( c, x ) && !has( f, x )){
			return f*myinteg( c, x );
		}
	}


	//int( pow( f, c ), x )				pow( f, c+1 ) * pow( c+1, -1 ) if c != -1,
 or ln( f ) if c == -1
	if( f.match( pow(wild(0),wild(1)), repls ) ){
		cout << "match int( pow( f, c ), x )" << endl;
		cout << "pow(wild(0),wild(1)) = " << repls << endl;

		ex f, c;
		for( exmap::const_iterator i=repls.begin(); i!=repls.end(); ++i){
			if(i->first.is_equal(wild(0)) ){
				f = i->second;
			}else if(i->first.is_equal(wild(1))){
				c = i->second;
			}
		}
		cout << "f = " << f << endl;
		cout << "c = " << c << endl;
	
		if( has( f, x ) && !has( c, x ) ){
			ex dft = f.diff(x,1);
			ex df = 1;
			cout << "df/dft = " << df/dft << endl;
			if( !has(df/dft,x) ){
				cout << "!has(df/dft,x)" << endl;
		 		if( c.is_equal(-1) ){
					return log( f ) * (df/dft);
				}else{
					cout << "df = " << df << endl;
					cout << "dft = " << dft << endl;
					cout << "(df/dft) = " << (df/dft) << endl;
					cout << "(1/dft) = " << (1/dft) << endl;
					cout << "pow(dft,-1) = " << pow(dft,-1) << endl;
					cout << "f = " << f << endl;
					cout << "c = " << c << endl;
					cout << "(pow( f, c+1 )/( c+1 )) = " << (pow( f, c+1 )/( c+1 )) << endl;
					cout << "pow( f, c+1 )*pow( c+1, -1) = " << pow( f, c+1 )*pow(
c+1, -1) << endl;
					cout << "(pow( f, c+1 )/( c+1 ))*(df/dft) = " << (pow( f, c+1 )/(
c+1 ))*(df/dft) << endl;
					cout << "pow( f, c+1 )*pow( c+1, -1) = " << pow( f, c+1 )*pow(
c+1, -1)*df*pow( dft, -1) << endl;
					return (pow( f, c+1 )/( c+1 )) * (df/dft);
				}
			}
		}

	}
	

	
	//int( pow( f, c ) * f', x )				pow( f, c+1 ) * pow( c+1, -1 ) if c
!= -1,  or ln( f ) if c == -1
	if( f.match( wild(0)*pow(wild(1),wild(2)), repls ) ){
		cout << "match int( pow( f, c ) * f', x )" << endl;
		cout << "wild(0)*pow(wild(1),wild(2)) = " << repls << endl;
	 	ex df, f, c;
		for( exmap::const_iterator i=repls.begin(); i!=repls.end(); ++i){
			if(i->first.is_equal(wild(0)) ){
				df = i->second;
			}else if(i->first.is_equal(wild(1))){
				f = i->second;
			}else if(i->first.is_equal(wild(2))){
				c = i->second;
			}
		}

		cout << "f' = " << df << endl;
		cout << "f = " << f << endl;
		cout << "c = " << c << endl;
	
		if( has( f, x ) && !has( c, x ) ){
			ex dft = f.diff(x,1);
			cout << "df/dft = " << df/dft << endl;
			if( !has(df/dft,x) ){
				cout << "!has(df/dft,x)" << endl;
		 		if( c.is_equal(-1) ){
					return log( f ) * (df/dft);
				}else{
					return pow( f, c+1 )*pow( c+1, -1) * (df/dft);
				}
			}
		}
	}
	

	return 0;
}


More information about the GiNaC-devel mailing list