[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