libgiac context *

Librairie C++ de calcul formel/ C++ symbolic computation library

Modérateur : xcasadmin

frederic han
Messages : 1137
Inscription : dim. mai 20, 2007 7:09 am
Localisation : Paris
Contact :

libgiac context *

Message par frederic han » lun. févr. 13, 2012 10:29 pm

Bonjour,

J'essaye de faire un peu de cython avec giac, et je ne sais pas trop ou mettre le pointeur de context ni pas tellement a quoi cela sert , est ce qu'il en faut un pour toute la librairie ou plutot un a chaque fois que je cree un gen?

J'ai aussi quelque soucis avec les interruptions, mais je peux en reproduire un peu sous giac:
Je fais des control C pour interrompre une factorisation de polynome parfois ca marche, mais il quitte aussi assez souvent. (Peut etre si je fais control C lorsqu'il est sous pari?)

>> g
g
// Time 0
7>> g:=factor(f):;
Evaluation time: 1.4
"Done"
// Time 1.41
8>> g:=factor(f):;
^CCtrl-C pressed (pid 27407)
Thread 139640069506816 has been cancelled
"Aborted"
// Time 1.04
9>> g:=factor(f):;
^CCtrl-C pressed (pid 27407)
Thread 139640061114112 has been cancelled
"Aborted"
// Time 0.56
10>> g:=factor(f):;
^CCtrl-C pressed (pid 27407)
Thread 139640052721408 has been cancelled
"Aborted"
// Time *** *** *** bug in PARI/GP (Segmentation Fault), please report0.58
11>> bug in PARI/GP (Segmentation Fault), please report

qu'en penses tu?
Fred

parisse
Messages : 5743
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: libgiac context *

Message par parisse » mar. févr. 14, 2012 7:32 am

salut,

le pointeur de contexte est là pour permettre l'exécution en parallèle de plusieurs sessions (par exemple si tu ouvres plusieurs onglets dans xcas), chaque session a son propre pointeur de contexte, ce qui permet d'éviter les collisions (mode mais aussi valeur des variables). Tu n'as probablement besoin que d'un pointeur de contexte pour commencer, après si ton appli devient plus complexe, tu en auras peut-etre besoin de plus.
Concernant control-C, en principe l'appui dessus met une variable globale ctrl_c à true, et ensuite certaines fonctions (par exemple +) vont exécuter control_c() qui teste cette variable et exécute une exception si elle est vraie. Ca ne devrait pas passer par PARI (le message est juste parce que pari met un handler à lui en cas de segfault je pense). Le probleme vient plutot des threads (que je ne sais peut-etre pas bien gérer), l'exception peut provoquer un arret du thread et il y a probablement des erreurs dans la gestion de l'allocation mémoire à ce moment-là (c'est pour ça que c'est difficile à reproduire, peut-etre qu'il faudrait essayer avec valgrind).

frederic han
Messages : 1137
Inscription : dim. mai 20, 2007 7:09 am
Localisation : Paris
Contact :

Re: libgiac context *

Message par frederic han » mer. févr. 15, 2012 8:30 am

Salut,

J'ai l'impression que je dois faire comme dans icas.cc sinon control C tue tout.

donc dans cython j'execute:

signal(SIGINT,GIAC_ctrl_c_signal_handler)
GIAC_ctrl_c=0
alors control C a l'air de bien etre intercepte, mais je ne peux plus refaire appel a giac pour executer car il reste dans cet etat (terminate called recursively). Mais les objets sont encore la, je peux les afficher, donc ca n'est pas plante. Que faut il reinitialiser, y a t'il une fonction qui fait tout ca?

Merci Fred

parisse
Messages : 5743
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: libgiac context *

Message par parisse » mer. févr. 15, 2012 9:29 am

Est-ce que tu lances l'evaluation dans un thread separe ou directement dans ta fonction principale? Si c'est directement dans ta fonction principale, tu devrais juste avoir a remettre ctrl_c a 0. Mais je ne sais pas du tout comment cython gere les exceptions.
Sinon tu peux utiliser un thread a part, regarde comment fonctionne icas_eval dans Xcas1.cc. Le bouton STOP de xcas peut arreter le calcul en cours de 2 manieres: soit par ctrl-c et exception (mais ca suppose que le calcul en cours teste ctrl_c), soit par arret du thread (ca ne suppose pas que le calcul teste ctrl_c, mais c'est sans doute plus risque parce que les variables allouees ne doivent pas etre correctement libereees): cf. History_cb_stop_button dans History.cc.

frederic han
Messages : 1137
Inscription : dim. mai 20, 2007 7:09 am
Localisation : Paris
Contact :

Re: libgiac context *

Message par frederic han » lun. févr. 20, 2012 2:50 pm

Salut,

J'ai tente de faire une classe python qui pointe vers un gen et de faire des essais de stabilite et vitesse.
J'en suis la (j'ai juste mis quelques conversions):
[url]http://people.math.jussieu.fr/~han/xcas/giacpy[/url]
J'arrive a interrompre par exemple la factorisation sans perdre les variables d'avant.

J'ai des questions betes:

* Je suis un peu perdu dans les types pour les entiers gmp. il y a des my_gmp et ... on est senses utiliser quoi pour communiquer avec un gmp externe a giac. (probablement faudra il le recopier)

* Est ce que si je fais pour coller deux gen afin d'utiliser gcd:
def giacgcd(Pygen a, Pygen b):
cdef gen result
ressetctrl_c()
try:
result=gen( GIAC_makenewvecteur(a.gptr[0],b.gptr[0]) ,<short int>2)
result=GIAC_gcd(result,context_ptr)
return _wrap_gen(result)
except:

le vecteur intermediaire cree avec maknewvecteur sera libere en sortant de la fonction?

Si vous avez des commentaires ou des idees (par exemple pour les ameliorer listes cf __iter__)

a+
Fred

parisse
Messages : 5743
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: libgiac context *

Message par parisse » lun. févr. 20, 2012 3:13 pm

Salut:
il y a 2 types entiers dans giac, les courts <2^31 sont codes avec des int machines (x.val si x.type==_INT_), les longs avec des gmp (tu peux tester avec x.type si x est de type gen). Pour acceder aux longs (si x.type==_ZINT), tu peux utiliser la macro x.__ZINTptr qui est un pointeur vers un mpz_t, ensuite toutes les fonctions C de GMP s'appliquent dessus, par exemple pour copier un mpz_t de giac vers l'exterieur tu peux faire en C:
mpz_t m;
mpz_init_set(m,*x._ZINTptr);
Si tu utilises des mpz_t externes, oui il faudra surement les recopier (a moins de creer un constructeur ad-hoc avec un pointeur de reference initialise a 2 ou a -1), tu as un constructeur pour ca
gen(const mpz_t & m);

Pour le pgcd, oui les vecteurs crees par makenewvecteur et mises dans un gen seront automatiquement liberes lorsque leur compteur de reference descendra a 0. Tu peux aussi creer des vecteurs avec makevecteur (pas de pointeur visible). Pour le gen genere, si c'est une sequence d'arguments, il vaut mieux faire gen(vecteur,_SEQ__VECT), cf. dispatch.h pour la liste des sous-types de vecteurs. Certaines fonctions reagissent en effet differamment selon le sous-type de la liste d'arguments passes, on peut interpreter le gen comme un argument de type vecteur ou comme plusieurs arguments, et le sous-type sert a lever l'indetermination.

frederic han
Messages : 1137
Inscription : dim. mai 20, 2007 7:09 am
Localisation : Paris
Contact :

Re: libgiac context *

Message par frederic han » jeu. févr. 23, 2012 12:00 am

Salut, merci pour ces reponses,

mais depuis python ca n'est pas clair que toutes ces methodes fonctionnent. La seule que j'ai reussi est:

gen(const mpz_t &)

qui marche donc bien sous sage.

En revanche j'ai constate cela que je trouve bizarre:

1) normal(f) que je stoppe par CTRL C renvoie tout de meme quelque chose: f. c'est vraiment voulu? Ex factor(f) interrompu ne fait pas ca. Lors d'une affectation interrompue a=normal(f) alors a est affecte.
2) a**b ou b est un mpz_t bascule en exp(b * ln(a)). Il y a un an ou 2 on gardait une forme inerte de a**b. on pouvait meme la passer a mod qui pouvait la calculer.
3) Je n'arrive pas a tuer ifactor depuis python, alors que factor se stoppe bien et est stable. (j'ai juste utilise la methode du ctrl c)

sinon j'ai l'impression d'avoir pas mal avance, j'ai des indices qui marchent depuis python ainsi que l'appel d'une fonction giac cree par l'utilisateur depuis python.

NB: Les entiers long de python (hors sage) ne sont pas des mpz_t, du coup je n'ai rien trouve mieux que de les convertir via des string.


a+

parisse
Messages : 5743
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: libgiac context *

Message par parisse » jeu. févr. 23, 2012 7:46 am

frederic han a écrit :Salut, merci pour ces reponses,

mais depuis python ca n'est pas clair que toutes ces methodes fonctionnent. La seule que j'ai reussi est:

gen(const mpz_t &)

qui marche donc bien sous sage.
Salut,
de toutes façons les autres méthodes doivent aussi copier le mpz_t donc c'est aussi efficace.
En revanche j'ai constate cela que je trouve bizarre:

1) normal(f) que je stoppe par CTRL C renvoie tout de meme quelque chose: f. c'est vraiment voulu? Ex factor(f) interrompu ne fait pas ca. Lors d'une affectation interrompue a=normal(f) alors a est affecte.
Oui, il y a un catch des erreurs par normal, du coup si tu tapes ctrl-c tu interromp le calcul et il renvoie l'argument non normalisé.
2) a**b ou b est un mpz_t bascule en exp(b * ln(a)). Il y a un an ou 2 on gardait une forme inerte de a**b. on pouvait meme la passer a mod qui pouvait la calculer.
Ca doit être un effet de bord d'un cas rajouté. On peut rajouter un test tout à la fin de pow dans gen.cc, juste avant sym_mult

Code : Tout sélectionner

      if (exponent.type==_ZINT && base.type!=_ZINT){
	if (base.type==_USER)
	  return pow_iterative(base,exponent,contextptr);
	return exp(exponent*log(base,contextptr),contextptr);
      }
      return new ref_symbolic(symbolic(at_pow,gen(makenewvecteur(base,exponent),_SEQ__VECT)));
    }  
  }
3) Je n'arrive pas a tuer ifactor depuis python, alors que factor se stoppe bien et est stable. (j'ai juste utilise la methode du ctrl c)
c'est normal je pense, parce que l'essentiel de ifactor se passe dans pari, qui ne teste bien sur pas ma variable ctrl c.
sinon j'ai l'impression d'avoir pas mal avance, j'ai des indices qui marchent depuis python ainsi que l'appel d'une fonction giac cree par l'utilisateur depuis python.
Excellente nouvelle!
NB: Les entiers long de python (hors sage) ne sont pas des mpz_t, du coup je n'ai rien trouve mieux que de les convertir via des string.


a+
Je pense que tu devrais pouvoir faire plus efficace avec des divisions euclidiennes par 2^31 et un algorithme de Horner.

Répondre