Dear all, For the international conference on mathematical software (http://www.icms2006.unican.es/), I was invited to show how some problems (http://fe.math.kobe-u.ac.jp/nobuki/DVD1/cdrom/icms2006/math-polyglot/toc.htm...) could be solved using GiNaC. Below you find the mail that I sent as an answer. If somebody here can think of better solutions to the problems, please post a message. Best wishes, Chris ---------- Forwarded message ---------- Dear Nobuki, Below are solutions to the problems, insofar GiNaC addresses them. Best wishes, Chris 1+2: Type into ginsh: 1+2; Answer: 3 integral(sqrt(1-x^2)): Symbolic integration is rather limited in GiNaC. It can only integrate polynomials. Fourier transform of exp(-x^2): same. Subgroups of S_5: GiNaC does not have functions to handle this kind of group theory problem. 4*arctan(1): Type into ginsh: 4*atan(1); Answer: Pi Drawing a parabola: GiNaC does not have graphics capabilities. It would be possible to do the numerics in GiNaC and let the plotting handle by some other library/utility. Drawing a saddle: same Define a function and load it: //////////////////////////// // Header file "myfun.h": // //////////////////////////// #include<ginac/ginac.h> GiNaC::ex myfun(const GiNaC::ex &x, const GiNaC::ex &y); //////////////////////////////////// // Implementation file "myfun.C": // //////////////////////////////////// #include "myfun.h" using namespace GiNaC; ex myfun(const ex &x, const ex &y) { return x+y; } /////////////////////// // Main file: test.C // /////////////////////// #include <iostream> #include <ginac/ginac.h> #include "myfun.h" using namespace std; using namespace GiNaC; int main() { cout << myfun(1,2) << endl; return 0; } Compiling myfun: g++ -O2 `ginac-config --cppflags` -c myfun.C Compiling main: g++ -O2 `ginac-config --cppflags` -c test.C Linking the two: g++ `ginac-config --libs` -o test test.o myfun.o Running: ./test Output: 3 Syllogistic: GiNaC does not have functions for logic. We can, however, write a function to test all posibilities in the thruthtable. Program: #include <iostream> #include <ginac/ginac.h> using namespace std; using namespace GiNaC; symbol True("True"); symbol False("False"); // Declare that implies is a GiNaC-function of two parameters. DECLARE_FUNCTION_2P(implies); // Automatic evaluation of implies in case that sufficiently many of the // paramters are given as "True" and "False" in order to know the result; // If not enough parameters are given, return the expression implies(x, y). ex implies_eval(const ex &x, const ex &y) { if (x==False) return True; if (x==True) if (y==False) return False; else if (y==True) return True; // The .hold() indicates that this result should not be further evaluated. return implies(x, y).hold(); } // Declare that the just-defined function is used for the evaluation of // the function implies. REGISTER_FUNCTION(implies, eval_func(implies_eval)); // Check if the expression x evaluates to True for any combination of // True/False substitued for the subexpressions given in l. bool check_truth(const ex &x, const lst &l) { // Get the size of l. int num_expr = l.nops(); // The number of possibilities to check. unsigned possibs = 1 << num_expr; // Loop over the possibilities to assign true and false to num_expr // subexpressions. for (unsigned i=0; i<possibs; ++i) { exmap m; // To store by what the subexpressions are going to be replaced. for (int j=0; j<num_expr; ++j) m[l.op(j)] = i&(1<<j) ? True : False; // Evaluate the expression for this particular posibility. ex result = x.subs(m); if (result != True) return false; // This is a C++ boolean, not ours. } return true; // This is a C++ boolean, not ours. } int main() { symbol P("P"); symbol Q("Q"); symbol R("R"); ex syllogistic = implies(implies(P,Q), implies(implies(Q,R), implies (P, R))); bool holds = check_truth(syllogistic, lst(P,Q,R)); if (holds) cout << syllogistic << " holds." << endl; else cout << syllogistic << " does not hold." << endl; return 0; } Output: implies(implies(P,Q),implies(implies(Q,R),implies(P,R))) holds. Powers of a matrix: In ginsh:
evalm( [[0,1],[1,1]] ^ 1 ); [[0,1],[1,1]] evalm( [[0,1],[1,1]] ^ 2 ); [[1,1],[1,2]] evalm( [[0,1],[1,1]] ^ 3 ); [[1,2],[2,3]] evalm( [[0,1],[1,1]] ^ 4 ); [[2,3],[3,5]] evalm( [[0,1],[1,1]] ^ 5 ); [[3,5],[5,8]] evalm( [[0,1],[1,1]]^1 * [[1],[1]] ); [[1],[2]] evalm( [[0,1],[1,1]]^2 * [[1],[1]] ); [[2],[3]] evalm( [[0,1],[1,1]]^3 * [[1],[1]] ); [[3],[5]] evalm( [[0,1],[1,1]]^4 * [[1],[1]] ); [[5],[8]] evalm( [[0,1],[1,1]]^5 * [[1],[1]] ); [[8],[13]]
Kernel of an integral matrix: Program: #include <iostream> #include <ginac/ginac.h> using namespace std; using namespace GiNaC; int main() { matrix m(2, 4); m = 1, 1, 1, 1, 0, 2, 4, 5; symbol x1("x1"), x2("x2"), x3("x3"), x4("x4"); matrix unknowns(4,1); unknowns = x1, x2, x3, x4; matrix rhs(2,1); rhs = 0, 0; cout << m.solve(unknowns, rhs) << endl; return 0; } Output: [[x3+3/2*x4],[-2*x3-5/2*x4],[x3],[x4]] Draw a graph of the Lorentz equation: Not sure what advantage GiNaC could bring here. No need for arbitrary precision arithmetic and GiNaC does not have plotting facilities. Elimination of variables: GiNaC does not have functions to solve systems of non-linear equations. Factorization of polynomials: GiNaC only has squarefree factorization and this problem cannot be solved that way.