Anillos Elementales¶
Cuando definimos matrices, vectores o polinomios, a veces es útil, incluso necesario, especificar el «anillo» sobre el que están definidos. Un anillo es una construcción matemática consistente en un conjunto de elementos sobre los que está bien definidas las operaciones de suma y producto; si la noción de anillo no te resulta familiar, probablemente sólo necesitas conocer estos cuatro anillos:
los enteros \(\{..., -1, 0, 1, 2, ...\}\), a los que nos referimos en Sage por
ZZ
.los números racionales – e.g., fracciones, o cocientes de números enteros –,
QQ
en Sage.los números reales,
RR
en Sage.los números complejos,
CC
en Sage.
Es importante conocer estas distinciones porque el mismo polinomio, por ejemplo, puede ser tratado de forma diferente dependiendo del anillo sobre el que se ha definido. Por ejemplo, el polinomio \(x^2-2\) tiene dos raíces, \(\pm \sqrt{2}\). Estas raíces no son racionales, así que si trabajamos con polinomios con coeficientes racionales, el polinomio es irreducible. Sin embargo, si los coeficientes son números reales, el polinomio factoriza como producto de dos factores lineales. En el siguiente ejemplo, los conjuntos de polinomios se llaman «ratpoly» y «realpoly», aunque no usaremos estos nombres; observa sin embargo que las cadenas «.<t>» y «.<z>» sirven para dar nombre a las variables usadas en cada caso.
sage: ratpoly.<t> = PolynomialRing(QQ)
sage: realpoly.<z> = PolynomialRing(RR)
>>> from sage.all import *
>>> ratpoly = PolynomialRing(QQ, names=('t',)); (t,) = ratpoly._first_ngens(1)
>>> realpoly = PolynomialRing(RR, names=('z',)); (z,) = realpoly._first_ngens(1)
ratpoly.<t> = PolynomialRing(QQ) realpoly.<z> = PolynomialRing(RR)
Veamos el punto que hicimos antes sobre factorizar \(x^2-2\):
sage: factor(t^2-2)
t^2 - 2
sage: factor(z^2-2)
(z - 1.41421356237310) * (z + 1.41421356237310)
>>> from sage.all import *
>>> factor(t**Integer(2)-Integer(2))
t^2 - 2
>>> factor(z**Integer(2)-Integer(2))
(z - 1.41421356237310) * (z + 1.41421356237310)
factor(t^2-2) factor(z^2-2)
Comentarios similares se aplican a las matrices: la forma reducida por filas de una matriz puede depender del anillo en que está definida, al igual que sus autovalores y autofunciones. Hay más construcciones con polinomios en la sección Polinomios, y más construcciones con matrices en Álgebra Lineal.
El símbolo I
representa la raíz cuadrada de \(-1\); i
es un
sinónimo de I
. Por supuesto, no es un número racional:
sage: i # raíz cuadrada de -1
I
sage: i in QQ
False
>>> from sage.all import *
>>> i # raíz cuadrada de -1
I
>>> i in QQ
False
i # raíz cuadrada de -1 i in QQ
Nota: El código siguiente puede no funcionar como esperas si hemos asignado
otro valor a la variable i
, por ejemplo si la hemos usado como variable
interna de un bucle. En este caso, podemos devolver i
a su valor original:
sage: reset('i')
>>> from sage.all import *
>>> reset('i')
reset('i')
Hay una sutileza al definir números complejos: el símbolo i
representa una
raíz cuadrada de \(-1\), pero es una raíz formal como elemento de un cuerpo
de números algebráicos.
Ejecutando CC(i)
o CC.0
o CC.gen(0)
obtenemos el número complejo
de coma flotante que es la raíz cuadrada de \(-1\).
sage: i = CC(i) # número complejo de coma flotante
sage: i == CC.0
True
sage: a, b = 4/3, 2/3
sage: z = a + b*i
sage: z
1.33333333333333 + 0.666666666666667*I
sage: z.imag() # parte imaginaria
0.666666666666667
sage: z.real() == a # conversión automática antes de la comparación
True
sage: a + b
2
sage: 2*b == a
True
sage: parent(2/3)
Rational Field
sage: parent(4/2)
Rational Field
sage: 2/3 + 0.1 # conversión automática antes de la suma
0.766666666666667
sage: 0.1 + 2/3 # las reglas de conversión son simétricas en Sage
0.766666666666667
>>> from sage.all import *
>>> i = CC(i) # número complejo de coma flotante
>>> i == CC.gen(0)
True
>>> a, b = Integer(4)/Integer(3), Integer(2)/Integer(3)
>>> z = a + b*i
>>> z
1.33333333333333 + 0.666666666666667*I
>>> z.imag() # parte imaginaria
0.666666666666667
>>> z.real() == a # conversión automática antes de la comparación
True
>>> a + b
2
>>> Integer(2)*b == a
True
>>> parent(Integer(2)/Integer(3))
Rational Field
>>> parent(Integer(4)/Integer(2))
Rational Field
>>> Integer(2)/Integer(3) + RealNumber('0.1') # conversión automática antes de la suma
0.766666666666667
>>> RealNumber('0.1') + Integer(2)/Integer(3) # las reglas de conversión son simétricas en Sage
0.766666666666667
i = CC(i) # número complejo de coma flotante i == CC.0 a, b = 4/3, 2/3 z = a + b*i z z.imag() # parte imaginaria z.real() == a # conversión automática antes de la comparación a + b 2*b == a parent(2/3) parent(4/2) 2/3 + 0.1 # conversión automática antes de la suma 0.1 + 2/3 # las reglas de conversión son simétricas en Sage
Veamos más ejemplos de anillos elementales en Sage. Como mencionamos antes,
nos podemos referir al anillo de números racionales usando QQ
, o también
RationalField()
(field, o cuerpo, se refiere a un anillo en el que
el producto es conmutativo y todo elemento excepto el cero tiene un inverso
para la multiplicación. De este modo, los racionales son un cuerpo, pero los
enteros no:
sage: RationalField()
Rational Field
sage: QQ
Rational Field
sage: 1/2 in QQ
True
>>> from sage.all import *
>>> RationalField()
Rational Field
>>> QQ
Rational Field
>>> Integer(1)/Integer(2) in QQ
True
RationalField() QQ 1/2 in QQ
El número decimal 1.2
se considera que está en QQ
: los números
decimales, que también son racionales, se pueden convertir a racionales de
forma automática. Sin embargo, los números \(\pi\) y \(\sqrt{2}\) no son
racionales:
sage: 1.2 in QQ
True
sage: pi in QQ
False
sage: pi in RR
True
sage: sqrt(2) in QQ
False
sage: sqrt(2) in CC
True
>>> from sage.all import *
>>> RealNumber('1.2') in QQ
True
>>> pi in QQ
False
>>> pi in RR
True
>>> sqrt(Integer(2)) in QQ
False
>>> sqrt(Integer(2)) in CC
True
1.2 in QQ pi in QQ pi in RR sqrt(2) in QQ sqrt(2) in CC
En Sage también podemos trabajar con otros anillos, como cuerpos finitos, enteros \(p\)-ádicos, el anillo de los números algebraicos, anillos de polinomios y anillos de matrices. Veamos algunos de estos anillos:
sage: GF(3)
Finite Field of size 3
sage: # es necesario dar un nombre al generador si el número
sage: GF(27, 'a') # de elementos no es primo
Finite Field in a of size 3^3
sage: Zp(5)
5-adic Ring with capped relative precision 20
sage: sqrt(3) in QQbar # clausura algebraica de QQ
True
>>> from sage.all import *
>>> GF(Integer(3))
Finite Field of size 3
>>> # es necesario dar un nombre al generador si el número
>>> GF(Integer(27), 'a') # de elementos no es primo
Finite Field in a of size 3^3
>>> Zp(Integer(5))
5-adic Ring with capped relative precision 20
>>> sqrt(Integer(3)) in QQbar # clausura algebraica de QQ
True
GF(3) # es necesario dar un nombre al generador si el número GF(27, 'a') # de elementos no es primo Zp(5) sqrt(3) in QQbar # clausura algebraica de QQ