http://xcas.e.ujf-grenoble.fr/XCAS/view ... f=4&t=1760
giacpy crée en Python des objets de classe Pygen.
Cette classe permet d'utiliser la librairie C++ giac. Plus précisément elle offre acces à un objet de type
giac::gen en C++.
Pour passer de giac vers python il faudra donc dans la majorité des cas passer par des str:
Exemple: Le cas des entiers
Code : Tout sélectionner
>>> from giacpy import giac
>>> a=giac(2) # 2 dans giac
>>> b=a**100 # dans giac
>>> int(str(b)) # dans python (conversion correcte)
1267650600228229401496703205376
>>> type(int(str(b)))
<class 'int'>
>>> b # dans giac
1267650600228229401496703205376
Pour les entiers et les flottants, il existe une petite zone où l'on peut éviter le passage par les chaines: lorque l'objet giac représente un entier ou un flottant qui n'est pas stocké en multiprécision. C'est plus efficace, mais il faut être beaucoup plus prudent.
Avec les valeurs précédentes de a et b on a:
Code : Tout sélectionner
>>> a._type # un entier en C peut etre converti directement vers python
0
>>> b._type # un entier de type multiprecision (gmp)
2
>>> a._val # acces direct au 2 de python.
2
>>> type(a._val)
<class 'int'>
>>> b._val # pas de sens car b etait de type multiprecision.
653
Code : Tout sélectionner
>>> import giacpy
>>> c=giacpy.approx('pi',100) # dans giac on est en multiprecision
>>> c
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
>>> d=giacpy.approx('pi',14)
>>> d._type # on verifie que d n'est pas multiprecision.
1
>>> d._double # l'acces direct a bien un sens
3.1415926535897967
>>> type(d._double)
<class 'float'>
>>> c._type # flottant multiprecision
3
>>> c._double # acces direct n'a pas de sens
9.386415709344787e+303
>>> c._val # pas de sens non plus
2131451904
giacpy pour python n'offre un acces direct que pour les cas 0 et 1 via les attribus: ._val et ._double
NB: giacpy_sage (la version de giacpy pour sage) peut en plus partager les entiers gmp.
Code : Tout sélectionner
// from dispatch.h
// immediate type (without mem allocation) should be < _ZINT
_INT_= 0, // int val
_DOUBLE_= 1, // double _DOUBLE_val
// all type below or equal to _DOUBLE_ must be non pointers
_ZINT= 2, // mpz_t * _ZINTptr
_REAL= 3, // mpf_t * _REALptr
// all type strictly below _CPLX must be real types
_CPLX= 4, // gen * _CPLXptr
_POLY= 5, // polynome * _POLYptr
_IDNT= 6, // identificateur * _IDNTptr
_VECT= 7, // vecteur * _VECTptr
_SYMB= 8, // symbolic * _SYMBptr
_SPOL1= 9, // sparse_poly1 * _SPOL1ptr
_FRAC= 10, // fraction * _FRACptr
_EXT= 11, // gen * _EXTptr
_STRNG= 12, // string * _STRNGptr
_FUNC= 13, // unary_fonction_ptr * _FUNCptr
_ROOT= 14, // real_complex_rootof *_ROOTptr
_MOD= 15, // gen * _MODptr
_USER= 16, // gen_user * _USERptr
_MAP=17, // map<gen.gen> * _MAPptr
_EQW=18, // eqwdata * _EQWptr
_GROB=19, // grob * _GROBptr
_POINTER_=20, // void * _POINTER_val
_FLOAT_=21 // immediate, _FLOAT_val
Les listes giac disposent d'une conversion vers une liste de Pygen naturelle:
Code : Tout sélectionner
>>> L=giac(range(10)) # une liste/vecteur dans giac
>>> L
[0,1,2,3,4,5,6,7,8,9]
>>> tuple(L) # un tuple python contenant des Pygen
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
>>> L2=list(L) # une liste python contenant des Pygen
>>> 1/L2[5] # L2[5] est un Pygen donc son inverse est fait dans giac.
1/5
>>> L+L # addition au sens de giac (donc des vecteurs)
[0,2,4,6,8,10,12,14,16,18]
>>> 5*L
[0,5,10,15,20,25,30,35,40,45]
>>> 1/2*L # ! le 1/2 est du python3 on a donc demande 0.5*L !
[0.0,0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5]
>>> '1/2'*L
[0,1/2,2*1/2,3*1/2,4*1/2,5*1/2,6*1/2,7*1/2,8*1/2,9*1/2]
>>> L/2
[0,1/2,1,3/2,2,5/2,3,7/2,4,9/2]
>>> L2+L2 # Mais si L2 est une liste Python contenant des Pygen (ou autre chose) alors + est celui de python, c'est donc la concatenation des listes.
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]