Bonjour,
La classe Pygen va absorber les objets python et donner aux opérations le sens qu'elles ont dans giac/xcas. Techniquement elle ne garde qu'un pointeur vers un objet de type gen de la librairie C++ giac, ce qui permet de limiter le temps perdu en conversions.
Il est fort probable que from giacpy import * importe trop de mots (par exemple int)
Il y a quelques informations dans
from giacpy import giac
help(giac)
par exemple dans la partie: Lists of Pygen and Giac lists on voit que:
Code : Tout sélectionner
>>> l1=giac(range(10)); l2=[1/(i**2+1) for i in l1]
>>> sum(l2)
33054527/16762850
So l1+l1 is done in giac and means a vector addition. But l2+l2 is done in Python so it is the list concatenation.
>>> l1+l1
[0,2,4,6,8,10,12,14,16,18]
>>> l2+l2
[1, 1/2, 1/5, 1/10, 1/17, 1/26, 1/37, 1/50, 1/65, 1/82, 1, 1/2, 1/5, 1/10, 1/17, 1/26, 1/37, 1/50, 1/65, 1/82]
Les objets de type Pygen sont aussi appelables au sens de giac/xcas.
Ex:
Code : Tout sélectionner
>>> from giacpy import giac
>>> x,y=giac('x,y')
>>> P=x**3+y*x+1/y
>>> f=P.unapply(y)
>>> f(1+2*x+y)
x**3+(1+2*x+y)*x+1/(1+2*x+y)
>>> A=giac([[1,2],[3,4]])
>>> A[0,1] # dans giac/xcas les indices commencent a 0
2
>>> A(1,2) # mais si l'on prefere qu'ils commencent a 1 giac/xcas propose cette syntaxe.
2
>>> A*A
[[7,10],[15,22]]
>>> A.matpow('n') # comme je n'ai pas fait n=giac('n') avant on le met entre ' '
[[(sqrt(33)-3)*((sqrt(33)+5)/2)**n*sqrt(33)/66-(-sqrt(33)-3)*((-sqrt(33)+5)/2)**n*sqrt(33)/66,(sqrt(33)-3)*((sqrt(33)+5)/2)**n*(sqrt(33)+11)/132+(-sqrt(33)-3)*((-sqrt(33)+5)/2)**n*(-sqrt(33)+11)/132],[6*((sqrt(33)+5)/2)**n*sqrt(33)/66-6*((-sqrt(33)+5)/2)**n*sqrt(33)/66,6*((sqrt(33)+5)/2)**n*(sqrt(33)+11)/132+6*((-sqrt(33)+5)/2)**n*(-sqrt(33)+11)/132]]
>>> (A % 2).ker() # A a bien un noyau non nul dans Z/2Z
[[0 % 2,-1]]
(NB: comme A etait de type Pygen, A %2 a bien eu le sens pour giac.
NB:
Code : Tout sélectionner
>>> giac(1 % 2) # ici 1 %2 est celui de python donc 1 que l'on envoit a giac
1
>>> giac('1 % 2') #
1 % 2
>>> giac(1) % 2 # ici c'est l'operation au sens de giac xcas donc le 1 de Z/2Z
1 % 2
Il y a tres peu de types d'objets giac qui auraient un sens en python de base, et les entiers ne sont pas du tout les mêmes (alors que dans sage si) bref il faudra souvent passer par des strings.
Il y a quelques conversions utiles qui evitent les str:
Dans votre exemple précédent il suffisait de faire (idem avec un tuple):
C'est normal que les elements de cette liste restent du type Pygen, même 1/2 n'aurait pas le meme sens.
Un autre cas qui peut vous etre utile pour eviter de passer par des str est celui des flottants. Si l'objet giac correspond bien à un flottant (et non pas un flottant multiprecision) alors cela a un sens de le convertir directement avec l'attribu: _double
Code : Tout sélectionner
>>> a=giacpy.approx('pi,100')
>>> b=giacpy.approx('pi,14') # la taille d'un flottant peut dependre de votre architecture
>>> a._type # flottant multiprecision
3
>>> a._double # n'a pas de sens
3.434313810944179e+306
>>> b._type # flottant
1
>>> b._double # a bien un sens
3.1415926535897967
Par exemple pour convertir quelques dessins de giac vers sage j'avais fait cela:
Code : Tout sélectionner
def mplot(self):
"""
Basic export of some 2D plots to sage. Only generic plots are supported.
lines, circles, ... are not implemented
"""
xyscat=[]
xyplot=[]
plotdata=self
if not plotdata.type()=='DOM_LIST':
return
for G in plotdata:
if G.dim()>2: # it is not a pnt. Ex: scatterplot
for g in G:
xyscat=xyscat+[[(g.real())._double,(g.im())._double]]
else:
if G[1].type()=='DOM_LIST':
l=G[1].op()
else:
l=G[1][2].op()
xyplot=[[(u.real())._double,(u.im())._double] for u in l]
if (xyscat != []):
result=scatter_plot(xyscat)
else:
result=line(xyplot)
return result
Si vous voulez voir le code cython qui a permis de creer giacpy, il est la:
https://gitlab.math.univ-paris-diderot. ... giacpy.pyx