There are many Computer Algebra systems available that are capabale of performing
symbolic mathematics, such as reduce, maxima, mathematica, and matlab. Some
are free, others are pricey. The use of these packages itself is a major affair that can
require a whole course (Math 250 for example) that can teach only the most basic
operations.
We will take a different approach, with the attitude that is better to learn the underlying
programming and math skills, and design our own short and simple symbolic math “software”
programs by writing C++ code that uses the cln and GiNaC libraries.
Cln is a huge library of numeric and symbolic object classes, and GiNaC is a library that
extends the cln classes and adds class methods or functions that act on specific class members.
It is an example of object oriented programming at its finest. Naturally both packages were
designed and written by physicists to do Feynmann diagram calculations in high energy
physics.
differs from procedural programming in a fundamental way. In C, which is not object oriented, it is
possible to define very complex, heterogeneous data types called structs. Here is an example of a
struct;
struct Atom{
float position[3]; /* (x,y,z) for atom */ char *name; /* a string such as Li, Mn, Ar,... */ float momentum[3]; /* (p_x, p_y, p_z) */ int color[3]; /* RGB numbers for the color it is displayed with*/ } Atoms[200]; |
which is the variable declaration for an array of 200 such objects, each one having a variety of attributes. The struct members are the position[3], name, color[3] variables in the declaration. If in the program we wish to print out the values of these things, we would use dot notation
for(n=0;n<200;n++){
printf("%s at\n", Atoms[n].name); printf("(x,y,z)=(%f,%f,%f)\n", Atoms[n].position[0], Atoms[n].position[1], \ Atoms[n].position[2]); |
What C++ offers above and beyond this is the elevation of a struct to a class, which differs in
that a class can have functions, called class methods that act on class members as members
themselves. Furthermore one can create subclasses of a parent class, and these subclasses inherit
class members and properties of the parent, and can have additional members and properties of
their own.
A second feature of C++ is its input/output routines. These are highly overloaded in the sense
that when an object such as a string or int or float is passed to the output routine cout, you do
not need to tell it how to print by providing a format string like you do with printf, the machine
will figure out how to format the object for printing. This of course takes time, and C++ is
somewhat slower than C.
If you introduce a new class of objects, you can overload the cout operator and tell it how to print
instances of your new object.
The third feature of C++ is its relaxation of the rules regarding variable declaration. In C, you
must declare all variables before any are assigned values or used. In C++ this is not required, and
you can introduce or declare variables at any point in the program.
It is important to remember that C++ is C, with these additions and enhancements.
Most C programs will compile just fine with C++ compilers, but the reverse is not
true.
In C we would write
#include<stdio.h>
#include<math.h> int n; float dx,x,y; main(){ dx=0.01; for(n=0;n<100;n++){ x=(float)n*dx; y=sin(x); printf("%d\t%f\t%f\n",n,x,y); } } |
and compile the program with
gcc -o program program.c -lm
|
and in C++ we have
#include<iostream.h>
#include<math.h> int n; float dx,x,y; main(){ dx=0.01; for(n=0;n<100;n++){ x=(float)n*dx; y=sin(x); cout << "n = " << n << "\t" << x << "\t" << y << endl; } } |
and compile with
g++ -o program program.c -lm
|
although the -lm may not be necessary with many compilers.
Let’s write a program that will differentiate the function

#include <iostream>
#include <ginac/ginac.h> using namespace std; using namespace GiNaC; int n; main(){ symbol x("x"); symbol a("a"); const ex f=exp(-a*x*x); for(n=1;n<=10;n++){ cout << f.diff(x,n) << endl; } } |
We compile and run this program, and get the output below;
sohrab:~$ g++ -o test2 test2.cc -lcln -lginac
sohrab:~$ ./test2 -2*a*exp(-a*xˆ2)*x -2*a*exp(-a*xˆ2)+4*aˆ2*exp(-a*xˆ2)*xˆ2 -8*aˆ3*exp(-a*xˆ2)*xˆ3+12*aˆ2*exp(-a*xˆ2)*x 12*aˆ2*exp(-a*xˆ2)-48*aˆ3*exp(-a*xˆ2)*xˆ2+16*aˆ4*exp(-a*xˆ2)*xˆ4 -120*aˆ3*exp(-a*xˆ2)*x+160*aˆ4*exp(-a*xˆ2)*xˆ3-32*aˆ5*exp(-a*xˆ2)*xˆ5 -120*aˆ3*exp(-a*xˆ2)+64*aˆ6*exp(-a*xˆ2)*xˆ6+720*aˆ4*exp(-a*xˆ2)*xˆ2 -480*aˆ5*exp(-a*xˆ2)*xˆ4 1344*aˆ6*exp(-a*xˆ2)*xˆ5-128*aˆ7*exp(-a*xˆ2)*xˆ7+1680*aˆ4*exp(-a*xˆ2)*x -3360*aˆ5*exp(-a*xˆ2)*xˆ3 1680*aˆ4*exp(-a*xˆ2)+13440*aˆ6*exp(-a*xˆ2)*xˆ4-3584*aˆ7*exp(-a*xˆ2)*xˆ6 +256*aˆ8*exp(-a*xˆ2)*xˆ8-13440*aˆ5*exp(-a*xˆ2)*xˆ2 80640*aˆ6*exp(-a*xˆ2)*xˆ3-48384*aˆ7*exp(-a*xˆ2)*xˆ5+9216*aˆ8*exp(-a*xˆ2)*xˆ7 -512*aˆ9*exp(-a*xˆ2)*xˆ9-30240*aˆ5*exp(-a*xˆ2)*x -30240*aˆ5*exp(-a*xˆ2)+302400*aˆ6*exp(-a*xˆ2)*xˆ2-403200*aˆ7*exp(-a*xˆ2)*xˆ4 +161280*aˆ8*exp(-a*xˆ2)*xˆ6-23040*aˆ9*exp(-a*xˆ2)*xˆ8 +1024*aˆ10*exp(-a*xˆ2)*xˆ10 |
Below is another example illustrating some of the many polynomial functions for commuting
variables.
#include <iostream>
#include <ginac/ginac.h> using namespace std; using namespace GiNaC; main(){ symbol x("x"); symbol y("y"); ex Poly1=4*pow(x,3)*y +5*pow(y,2)*x -6*x*y; ex Poly2=Poly1.diff(x,1); ex Poly3=Poly1*Poly2; ex Poly4=pow(x,2)-4*x+4; ex Poly5=(x-2)*(x-1); ex Poly6=Poly4/Poly5; cout << Poly1.ldegree(x) << endl; cout << Poly2.coeff(x,2) << endl; cout << Poly6.normal() << endl; } |
Compile and run this program and determine what each of these operations does.
Below is yet another example illustrating how you can write programs that manipulate series
symbolically.
#include <iostream>
#include <ginac/ginac.h> using namespace std; using namespace GiNaC; main(){ symbol x("x"); symbol c("c"); ex f=1/sqrt(1-pow(x,2)/pow(c,2)); ex sf=f.series(x,6); cout << sf << endl; } |
Compile and run this program.
1. Find the coefficient of x1 in Large

2. Find the first ten derivatives of Large

3. Read through the GiNaC tutorial pages at http://talkitoaster.uwp.edu/290/GiNaC/ and
write a short program performing a symbolic operation not discussed in this handout.