Class Pygen
Modérateur : xcasadmin
Class Pygen
Bonjour.
J'apprends à utiliser la bibliothèque Giac dans Python.
Les objets créés sont du type "Pygen".
1) Pouvez-vous expliquer de quoi il s'agit ?
2) Je ne parviens pas à transformer les objets du type pygen en un autre type plus classique dans python (list, str, float, int ...). J'aimerais pouvoir le faire afin d'utiliser la bibliothèque Matplotlib. Comment faire ?
Un essai pour transformer une liste Pygen en une liste Python (hélas les éléments sont aussi du type Pygen) :
Merci de vos éclaircissements et aide bienvenue !
JP
J'apprends à utiliser la bibliothèque Giac dans Python.
Les objets créés sont du type "Pygen".
1) Pouvez-vous expliquer de quoi il s'agit ?
2) Je ne parviens pas à transformer les objets du type pygen en un autre type plus classique dans python (list, str, float, int ...). J'aimerais pouvoir le faire afin d'utiliser la bibliothèque Matplotlib. Comment faire ?
Un essai pour transformer une liste Pygen en une liste Python (hélas les éléments sont aussi du type Pygen) :
Merci de vos éclaircissements et aide bienvenue !
JP
-
- Messages : 1137
- Inscription : dim. mai 20, 2007 7:09 am
- Localisation : Paris
- Contact :
Re: Class Pygen
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:
Les objets de type Pygen sont aussi appelables au sens de giac/xcas.
Ex:
(NB: comme A etait de type Pygen, A %2 a bien eu le sens pour giac.
NB:
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
Par exemple pour convertir quelques dessins de giac vers sage j'avais fait cela:
Si vous voulez voir le code cython qui a permis de creer giacpy, il est la:
https://gitlab.math.univ-paris-diderot. ... giacpy.pyx
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]
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:
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.
Code : Tout sélectionner
from giacpy import giac
a=giac(2)
b=a**1000
c=int(str(b))
Dans votre exemple précédent il suffisait de faire (idem avec un tuple):
Code : Tout sélectionner
x1=list(a)
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
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
https://gitlab.math.univ-paris-diderot. ... giacpy.pyx
-
- Messages : 1137
- Inscription : dim. mai 20, 2007 7:09 am
- Localisation : Paris
- Contact :
Re: Class Pygen
Mon exemple avec la matrice modulaire n'etait pas tres bien choisi. Avec celui ci on voit mieux la différence entre le % de giac et celui de python:
alors que si l'on n'utilise que le % de python:
Code : Tout sélectionner
>>> from giacpy import giac
>>> A=giac([[2,1],[1,3]])
>>> (A % 5)
[[2 % 5,1 % 5],[1 % 5,-2 % 5]]
>>> (A % 5).ker()
[[-2 % 5,-1]]
Code : Tout sélectionner
>>> B=[[2 % 5, 1 % 5 ],[ 1 % 5 ,3 % 5]] # une liste de liste d'entiers python
>>> B
[[2, 1], [1, 3]]
>>> giac(B).ker()
[]
>>> B % 5 # n'a pas de sens pour une liste python.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for %: 'list' and 'int'
>>> giac(B) % 5 # ici on retrouve l'analogue de A
[[2 % 5,1 % 5],[1 % 5,-2 % 5]]
Re: Class Pygen
Merci pour cette longue réponse qui va me demander du temps de réflexion (et de digestion !)
J'en profite pour vous soumettre un résultat qui m'est apparu en faisant un essai de résolution d'équation. (J'ai trouvé cet exemple dans le mode d'emploi de xcas) : cos(2x)=1/2
Les 2 solutions modulo 2pi sont pi/6 et -pi/6
Avec solve j'obtiens pourtant des valeurs approchées : Qu'en pensez-vous ?
Bonne soirée et encore merci de m'accorder autant de votre temps.
Cordialement.
JP
J'en profite pour vous soumettre un résultat qui m'est apparu en faisant un essai de résolution d'équation. (J'ai trouvé cet exemple dans le mode d'emploi de xcas) : cos(2x)=1/2
Les 2 solutions modulo 2pi sont pi/6 et -pi/6
Avec solve j'obtiens pourtant des valeurs approchées : Qu'en pensez-vous ?
Bonne soirée et encore merci de m'accorder autant de votre temps.
Cordialement.
JP
-
- Messages : 1137
- Inscription : dim. mai 20, 2007 7:09 am
- Localisation : Paris
- Contact :
Re: Class Pygen
Oui car vous avez entré
qui en python3 fait 0.5 car giacpy ne modifie pas les opérations entre 2 objets python, il ne s'occupe que de celles entre 2 Pygen ou 1 Pygen et 1 autre. (Donc prudence avec / et % et 2 entiers python)
Vous avez donc fait:
Mais vous auriez pu faire:
ou bien comme cela c'est peut être plus naturel
Au fait je n'ai jamais su s'il existait un analogue de equal pour les inéquations,
@bernard, ca pourrait nous être utile.
Il y a un moyen de s'en sortir je l'explique dans la rubrique giacpy toute neuve.
Code : Tout sélectionner
1/2
Vous avez donc fait:
Code : Tout sélectionner
In [122]: equal(cos(2*x),0.5).solve()
Out[122]: list[-0.523598775598,0.523598775598]
Code : Tout sélectionner
In [123]: equal(cos(2*x),'1/2').solve()
Out[123]: list[-1/6*pi,1/6*pi]
In [124]: equal(cos(2*x),giac(1)/2).solve()
Out[124]: list[-1/6*pi,1/6*pi]
Code : Tout sélectionner
In [163]: (cos(2*x)-'1/2').solve()
Warning, argument is not an equation, solving cos(2*x)-1/2=0
Out[163]: list[-1/6*pi,1/6*pi]
In [164]: cos(2*x).equal('1/2').solve()
Out[164]: list[-1/6*pi,1/6*pi]
Au fait je n'ai jamais su s'il existait un analogue de equal pour les inéquations,
@bernard, ca pourrait nous être utile.
Il y a un moyen de s'en sortir je l'explique dans la rubrique giacpy toute neuve.
Re: Class Pygen
Il y a bien des fonctions pour les inequations: _superieur_strict, _superieur_equal, _inferieur_strict, _inferieur_equal