lundi 15 novembre 2021

Giac, Xcas, icas

La suite Giac, Xcas, icas est un ensemble de librairie C++, interface graphique, et interface console de calcul symbolique, de calcul en général et bien plus. Ici j'aborderai l'interface console en linux.

Autant l'avouer tout de suite, je ne connais que linux et j'utilise presque exclusivement icas qui est l'interface en console (dans un terminal) de préférence à Xcas qui lui utilise l'interface graphique (librairie LFTK). Les exemples donnés dans cette page sont donc copiés depuis un terminal. Ils se présentent sous la forme d'une ligne de commande, suivie de la ligne de réponse de Giac. Exemple :

7>> solve(x^2-3*x+2)
Attention, l'argument n'est pas une équation, on résout x^2-3*x+2=0
list[1,2]
8>> 

7>> est l'invite de commande (prompt) numéro 7 et à la ligne suivante la réponse de Giac.

Configuration

Configuration de Xcas

Il semblerait que le moyen d'ajuster FLTK aux écrans HiDPI soit d'augmenter la police. Une taille de 20 semble correcte pour mes yeux et mon écran. Menu : Cfg/Polices(toutes) et Cfg/Polices session. Remarque : Ce réglage est assez capricieux. Une valeur de la police de 18 donne une hauteur de la fenêtre de saisie inexploitable.

Utilisation en ligne de commande

Pour entrer dans l'interpréteur en ligne de commande, la commande à lancer est giac ou icas. Si Gnu readline est installé, on obtient une interface confortable.

Par défaut, l'interpréteur de commande affiche le temps d'exécution. Si l'on en a pas besoin il faut créer une variable d'environnement :

export GIAC_NO_TIME=1

Il m'a fallu lire le source de icas.cc pour dénicher cette option !

Car icas est livré sans aide (--help ou -h) ni man. Je me suis fendu de ce man page de icas pour combler cette lacune. Il est directement issu de Xcas reference card fourni par l'équipe Bernard Parisse et Renée De Graeve.

Comparaison avec sympy

Giac ne souffre pas des limitations dues à python :

Giac est assez permissif

21>> factor(x²-1)
(x-1)*(x+1)
24>> csolve(x³-1=0)
list[1,1/2*(i*sqrt(3)-1),1/2*((-i)*sqrt(3)-1)]

Premiers pas

Ma référence est Xcax au lycée ou en anglais Xcas reference card qui est une sorte de cheat sheet très concise et efficace.

Quelques fonctionnalités sont parfois plus difficiles à s'approprier :

Exemple :

0>> y:=cos(x)^2+sin(x)^2
cos(x)^2+sin(x)^2
1>> simplify(y)
1

On obtient immédiatement le résultat attendu.

Il n'en va pas de même avec les fonctions hyperboliques,

2>> z:=cosh(x)^2-sinh(x)^2
cosh(x)^2-sinh(x)^2
3>> simplify(z)
cosh(x)^2-sinh(x)^2
4>> lin(z)
1

simplify ne simplifie rien du tout, mais lin (i.e. linéarise les exponentielles) donne l'identité attendue. Le pendant de lin en trigo est tlin.

Remarque

La documentation Xcas reference card, signalée ci-dessus, omet la fonction lin, je l'ai rajoutée dans mon man page.

Notes d'utilisateur

Diagonalisation d'une matrice carrée

A:=[[2,-7/3],[3,-10/3]];
P,D:=jordan(A);

La fonction jordan renvoie la matrice de passage P et la matrice diagonale D. Il existe deux autres fonctions eigenvals et eigenvects qui renvoient les valeurs propres et les vecteurs propres sous forme de listes.

Résolution d'un système linéaire d'équations différentielles

Pour résoudre le système

$$\lbrace\begin{array}{ccc}x^\prime(t) & = & a_{11}.x(t)+ a_{12}.y(t) \\y^\prime(t) & = & a_{21}.x(t) + a_{22}.y(t) \end{array}$$

[[x,y]]:=desolve([z'=A*z,z(0)=[1000,10]],t,z);

où A est la matrice des $a_{ij}$, et $z(0)=[1000, 10]$ sont les conditions initiales $x_0$, $y_0$. C'est assez impressionnant !

Résolution d'une équation différentielle du premier ordre

latex(simplify(desolve(y'-x/(x²+1)*y=2x^3+x+1)));

donne

$\dfrac{3 c \sqrt{x^{2}+1}+2 x^{4}+x^{2}-3 \sqrt{x^{2}+1} \ln \left(\sqrt{x^{2}+1}-x\right)-1}{3}$

Programme en C++

Evaluation

La fonction cevaladapté de example, prend en paramètrer une expression mathématique ne contenant que des constantes (string) et renvoie son évaluation (un double).

/* eval.cc */
#include <string>
#include <iostream>
#include <giac/config.h>
#include <giac/giac.h>
using namespace std;
using namespace giac;
// eval
double eval(string s)
{
	context ct;
	gen e(s, &ct);
	e = eval(e, 1, &ct);
	gen f = _float(e, &ct);
	return f._DOUBLE_val;
}
// main
int main(int argc, char * argv[]) 
{
	double x;
	string s;
	cout << ("q: quit") << endl;
	while(true) {
		cout << "expression : ";
		cin >> s;
		if(s.compare("q") == 0) exit(0);
		x = eval(s);
		cout << x << endl;
	}
}

On compile avec g++ eval.cc -lgiac -lgpm

Latex

Je me suis servi du bout de code suivant pour vérifier la saisie de latex dans ce blog.

/* ltex.cc */
#include <giac/config.h>
#include <giac/giac.h>
using namespace std;
using namespace giac;
// $ ltex "ltex "x/(x²+1)""\frac{x}{x^{2}+1}"
int main(int argc, char * argv[]) 
{
	context ct;
	gen e(argv[1], &ct);
	e = eval(e, 1, &ct);
	cout << _latex(e, &ct) << endl;
}

iquo, irem

#include <giac/config.h>
#include <giac/giac.h>
using namespace std;
using namespace giac;
string
giac_div(const string s, const string s1, const string s2)
{
   context ct;
   gen e(s + "(" + s1 + ", " + s2 + ")", &ct);
   e = eval(e, 1, &ct);
   return print(e, &ct);
}
int main(int argc, char * argv[]) 
{
	string xs = "3-7*i", ys = "1+2*i";
	cout << xs << " \% " << ys << " = " <<  giac_div("iquo", xs, ys);
}

Sortie :

3-7*i \% 1+2*i = -2-3*i
Appuyez sur ENTRÉE ou tapez une commande pour continuer