Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

Laboratorio 1

110 views
Kernel: SageMath (stable)

Práctica 1 de SAGE

Veamos algunas funciones sobre enteros, y algunas propiedades de los objetos SAGE (Python). Vamos a empezar por la asignación: a=20!+1a=20!+1.

a=factorial(20)+1

Veamos su valor:

a
2432902008176640001

Otras funciones sobre enteros:

factor(a)
20639383 * 117876683047
euler_phi(a)
2432901890279317572

Doble asignación

a,b=123211413,32423124
a
123211413
b
32423124

Máximo común divisor

gcd(a,b)
3

Identidad de Bézout: (usando triple asignación)

[d,alpha,beta]=xgcd(a,b)
d, alpha, beta
(3, 4496651, -17087765)
alpha*a+beta*b==d
True
True or False and True
True

Congruencias:

s = 1449
Mod(s,5), Mod(s,9), Mod(s,2), Mod(s,19)
(4, 0, 1, 5)

Las funciones que hemos visto son “globales”. Pyton tiene otro tipo de funciones, las que son propias de cada objeto.

a=Mod(11,15) type(a)
<type 'sage.rings.finite_rings.integer_mod.IntegerMod_int'>
parent(a)
Ring of integers modulo 15
a+4
0
a^14
1
a=38975239857938475
a.is_prime()
False
b
32423124
b.is_prime()
False
a=13^2 a.is_prime_power()
True
a.next_prime()
173

Una forma de encontrar un número primo de kk cifras (o quizá k+1k+1):

ZZ
Integer Ring
k=6 a=ZZ.random_element(10^(k-1), 10^k) p=next_prime(a) p
263489

Más directo, y usando la ayuda

random_prime?
random_prime(10^k, lbound=10^(k-1))
124577

A veces hay funciones “repetidas”

a.factorial() == factorial(a)
True
a.binomial(2)
34710723460
binomial(a,2)
34710723460
a.xgcd(b)
(4, 3209210, -26079)

Más sobre congruencias

a=Mod(1,28)

aa "parece" un entero, pero en realidad es otra cosa, un "entero modular"

type(a)
<type 'sage.rings.finite_rings.integer_mod.IntegerMod_int'>

Un poco más claro:

parent(a)
Ring of integers modulo 28
a+27
0

Otra forma de definir el mismo aa, usando el anillo Z/Z28\mathbb{Z}/\mathbb{Z}28

ZZ28 = IntegerModRing(28) ZZ28
Ring of integers modulo 28

Así se “fuerza” a convertir un entero en un elemento del anillo:

ZZ28=IntegerModRing(28)
b=ZZ28(1)+ZZ28(13) b
14
parent(b)
Ring of integers modulo 28
b^123413
0
b.is_unit()
c=b+1 c.is_unit()
ZZ28.multiplication_table('digits')

Algunas funciones sobre anillos

ZZ28.is_field()
ZZ28.is_integral_domain()

La lista de las unidades:

L=ZZ28.list_of_elements_of_multiplicative_group() L
parent(L[4])
c
c.is_unit()

Como cc es una unidad, tiene inverso

c^(-1)

Pero bb...

b
b^(-1)

## Anillos de polinomios

R.<x,y,z>=PolynomialRing(QQ) # = QQ[x,y,z]
f1=x^2+y^2-z f2=2*z-x*y
parent(f1)
y*f1-x*f2

Veamos un anillo con algo más de estructura: polinomios en una variable

K.<x>=PolynomialRing(QQ)

Cociente y resto:

g=x^12-x^4-1 h=x^5+x^4-2*x^3+6*x^2+24*x+1 q,r=g.quo_rem(h)
q,r

Grupos simétricos

Veamos primero cómo se definen los grupos simétricos en SAGE.

G=SymmetricGroup(4)
G
order(G)

Para ver los elementos de G, podemos pedirle que nos los enseñe en una lista

list(G)

SAGE presenta los elementos como producto de ciclos disjunto. Para manejar los elementos del grupo, podemos pedirle los elementos de la lista. SAGE numera las listas EMPEZANDO POR EL ELEMENTO CERO.

L=list(G)
L[0]
L[1]
L[1]*L[2]

Cuidado! Sage compone de izquierda a derecha, y no como estamos habituados de derecha a izquierda!

L[2]^(-1)

Si queremos dar un elemento de S_4 directamente, debemos escribirlo como una lista de ciclos disjuntos [C_1, C_2, ..., C_k]. Tenemos que especificar que esta lista debe mirarse como un elemento de G, usando la expresión G(...).

G([(1, 2)])
G([(1, 2)])*G([(1, 3, 2)])
G([(1, 2), (3, 4)])

Operaciones con elementos:

sigma= G([(1, 2), (3, 4)])

Para ver qué cosas se pueden hacer con sigma, tecleamos sigma. y utilizamos la tecla autocompletar:

sigma.
sigma.order()
sigma.sign()

Si queremos información sobre un comando concreto, lo escribimos, seguido por una interrogación ?

sigma.sign?

Las permutaciones son funciones, y, como tales, se pueden evaluar:

sigma(2)

Subgrupos

Calculamos todos los subgrupos de G.

G.subgroups()

Para definir un subgrupo, especificamos los generadores.

H=G.subgroup([(3,4), (2,4,3)])
H
order(H)

De nuevo, podemos pedirle a SAGE que nos de una lista con los elementos de H.

H.list()

También podemos pedirle un conjunto de generadores.

H.gens()

SAGE recuerda que H está definido como un subgrupo de G.

H.ambient_group()

Predicados para grupos

G.is_commutative()
G.is_cyclic()
H.is_normal()
G.exponent()
G.random_element()

Un comando muy útil es cayley_table, que nos da la tabla de multiplicar del grupo

G.cayley_table()

Como podéis ver, SAGE ha reemplazado los elementos por letras. Para saber a qué elemento se corresponde cada letra, podéis usar:

T = H.cayley_table() headings = T.row_keys() headings[2]

Algunos predicados relacionados con la asignatura de Estructuras Algebraicas

H.is_simple()
G.is_solvable()
G.center()
G.normalizer(H)
G.centralizer(H)

Cuando trabajamos con un grupo muy grande, la cantidad de subgrupos es enorme. A veces puede ser útil tener una lista de subgrupos salvo conjugación.

G.conjugacy_classes_subgroups()

Grupo cociente

Para construir grupos cociente, lo primero que tenemos que hacer es encontrar los subgrupos normales de un grupo

G.normal_subgroups()
V = G.subgroup(G([(1,3), (2, 4)]), G([(1, 4), (2,3)]))
[(1,3)(2,4), (1,4)(2,3)]
gamma1=G([(1,3), (2, 4)]) gamma2= G([(1, 4), (2,3)]) V= G.subgroup([gamma1, gamma2])
V.is_normal()
Q=G.quotient(V)
Q
list(Q)

SAGE nos da un grupo isomorfo al grupo cociente, pero no conserva el morfismo natural G -> G/V.

Q.is_abelian()

Luego sabemos por teoría de grupos que Q debe ser isomorfo al grupo simétrico de 3 elementos.

Q.is_isomorphic(SymmetricGroup(3))

Homomorfismos

Para definir homomorfimos entre grupos de permutaciones o subgrupos de éstos, debemos dar una lista ordenada con las imagenes de los generadores del grupo de origen

G.gens()
f=PermutationGroupMorphism(G, G, [(1, 3, 2, 4), (1, 3)])
f
Hemos construido un morfismo que lleva (1, 2, 3, 4) en (1, 3, 2, 4) y (1, 2) en (1, 3)
f([(1, 3, 4)])
for i in G: print (i, f(i))

Pero, cuidado! SAGE "no se da cuenta" si definimos algo que no tiene sentido...

g=PermutationGroupMorphism(G, G, [(1, 2, 3), (1, 2)])
g
hasta que no lo evaluamos:
for i in G: print (i, g(i))
f.kernel()
f.image(G)

Grupos abelianos

Para trabajar con grupos abelianos, SAGE tiene comandos específicos: El comando AbelianGroup([a, b, ..., l) define el grupo producto de grupos cíclicos C_a x C_b x ... x C_l.

A.<a,b,c> = AbelianGroup([2,4,5])
A
A.is_isomorphic(AbelianGroup([2, 20]))
a
a^2

Otros grupos

DihedralGroup(4)
CyclicPermutationGroup(5)
AlternatingGroup(5)
KleinFourGroup()

Ejercicios

  1. Construye un homomorfismo sobreyectivo de S_4 en C_2. (Ayuda: utiliza la paridad de las permutaciones).

S4 = SymmetricGroup(4) # S4 C2 = SymmetricGroup(2) # S2 = C2
S4.gens() # hay que enviar estos elementos ...
C2.gens() # en estos
a = S4.gens()[0] b = S4.gens()[1] c = C2.gens()[0] a, b ,c
  1. Encuentra todos los cocientes de S_4 de orden 6. ¿Cuáles son abelianos?

  1. Encuentra todos los grupos abelianos de orden 72 salvo isomorfismo.