[GiNaC-list] Re: math-polyglot (fwd)

Chris Dams Chris.Dams at mi.infn.it
Tue Jul 11 16:57:06 CEST 2006


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.html)  
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.



More information about the GiNaC-list mailing list