GiNaC is a C++ library. It has been developed to become a replacement engine for xloops which in the past was powered by the Maple CAS. Its design is revolutionary in a sense that contrary to other CAS it does not try to provide extensive algebraic capabilities and a simple programming language but instead accepts a given language (C++) and extends it by a set of algebraic capabilities. The name GiNaC is an iterated and recursive abbreviation for GiNaC is Not a CAS, where CAS stands for Computer Algebra System.
As a little example that shows some syntactical candy possible with GiNaC, here is a complete C++-program that uses the defining equation for (normalized) Laguerre Polynomials Ln(z)==ez(d/dz)n(zne-z)/n! and the associated Laguerre Polynomials Ln,m(z)==(d/dz)mLn(z) to compute the first few Laguerre polynomials in the symbolic variable x. Of course it is not optimized for efficiency. A faster version would not use Rodrigues' definition with the derivative. Instead, this version is optimized for elegance:
#include <iostream> #include <ginac/ginac.h> using namespace std; using namespace GiNaC; /* Laguerre Polynomial L_n(z) == exp(z)*(d/dz)^n (z^n*exp(-z)) / n! */ ex LaguerrePoly(int n, const symbol & z) { const ex LKer = exp(-z); return normal(diff(pow(z, n)*LKer, z, n) / LKer) / factorial(n); } /* Associated Laguerre Polynomial L_{n,m}(x) == (d/dx)^m L_n(x). */ ex LaguerrePoly(int n, int m, const symbol & z) { return LaguerrePoly(n, z).diff(z, m); } int main() { symbol x("x"); for (int i=0; i<7; ++i) { cout << " L_" << i << "(" << x << ") == " << LaguerrePoly(i, x) << endl; for (int j=1; j<=i; ++j) { cout << "L_{" << i << ',' << j << "}(" << x << ") == " << LaguerrePoly(i, j, x) << endl; } cout << endl; } return 0; }
When you compile this program and run it, it will type out:
L_0(x) == 1 L_1(x) == 1-x L_{1,1}(x) == -1 L_2(x) == 1-2*x+1/2*x^2 L_{2,1}(x) == -2+x L_{2,2}(x) == 1 L_3(x) == 1-3*x+3/2*x^2-1/6*x^3 L_{3,1}(x) == -3+3*x-1/2*x^2 L_{3,2}(x) == 3-x L_{3,3}(x) == -1 L_4(x) == 1-4*x+3*x^2-2/3*x^3+1/24*x^4 L_{4,1}(x) == -4+6*x-2*x^2+1/6*x^3 L_{4,2}(x) == 6-4*x+1/2*x^2 L_{4,3}(x) == -4+x L_{4,4}(x) == 1 L_5(x) == 1-5*x+5*x^2-5/3*x^3+5/24*x^4-1/120*x^5 L_{5,1}(x) == -5+10*x-5*x^2+5/6*x^3-1/24*x^4 L_{5,2}(x) == 10-10*x+5/2*x^2-1/6*x^3 L_{5,3}(x) == -10+5*x-1/2*x^2 L_{5,4}(x) == 5-x L_{5,5}(x) == -1 L_6(x) == 1-6*x+15/2*x^2-10/3*x^3+5/8*x^4-1/20*x^5+1/720*x^6 L_{6,1}(x) == -6+15*x-10*x^2+5/2*x^3-1/4*x^4+1/120*x^5 L_{6,2}(x) == 15-20*x+15/2*x^2-x^3+1/24*x^4 L_{6,3}(x) == -20+15*x-3*x^2+1/6*x^3 L_{6,4}(x) == 15-6*x+1/2*x^2 L_{6,5}(x) == -6+x L_{6,6}(x) == 1
Currently, GiNaC's capabilities include:
The capabilites still missing (but would be nice to see implemented) are listed in the ToDo List.
For a more in-depth description of GiNaC we refer to the tutorial which contains many more examples.