# [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,

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;

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);

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.

Define a function and load it:
////////////////////////////
////////////////////////////
#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 * [,] );
[,]
> evalm( [[0,1],[1,1]]^2 * [,] );
[,]
> evalm( [[0,1],[1,1]]^3 * [,] );
[,]
> evalm( [[0,1],[1,1]]^4 * [,] );
[,]
> evalm( [[0,1],[1,1]]^5 * [,] );
[,]

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.

```