Module: sage.structure.factorization
Factorizations
The Factorization
class derives from list
, so it can
print nicely and be manipulated like a list of prime-exponent pairs or
easily turned into a list. For example, we factor the integer
:
sage: F = factor(-45)
This returns an object of type Factorization
:
sage: type(F) <class 'sage.structure.factorization.Factorization'>
It prints in a nice factored form:
sage: F -1 * 3^2 * 5
There is an underlying list representation, which ignores the unit part (!).
sage: list(F) [(3, 2), (5, 1)] sage: isinstance(F, list) False
We can access the Factorization
F itself as if it were a list:
sage: F[0] (3, 2) sage: F[1] (5, 1)
To get at the unit part, use the unit_part
function:
sage: F.unit_part() -1
All factorizations are immutable. Thus if you write a function that returns a cached version of a factorization, you do not have to return a copy.
sage: F = factor(-12); F -1 * 2^2 * 3 sage: F[0] = (5,4) Traceback (most recent call last): ... TypeError: 'Factorization' object does not support item assignment
This more complicated example involving polynomials also illustrates +that the unit part is not discarded from factorizations.
sage: x = QQ['x'].0 sage: f = -5*(x-2)*(x-3) sage: f -5*x^2 + 25*x - 30 sage: F = f.factor(); F (-5) * (x - 3) * (x - 2) sage: F.unit() -5 sage: expand(F) -5*x^2 + 25*x - 30
The underlying list is the list of pairs
, where
is prime and
is an integer. The unit part is discarded by
the list.
sage: list(F) [(x - 3, 1), (x - 2, 1)] sage: len(F) 2 sage: F[1] (x - 2, 1)
In the ring
, the integer
is not a unit, so the
factorization has three factors:
sage: x = ZZ['x'].0 sage: f = -5*(x-2)*(x-3) sage: f -5*x^2 + 25*x - 30 sage: F = f.factor(); F (-1) * 5 * (x - 3) * (x - 2) sage: F.unit() -1 sage: list(F) [(5, 1), (x - 3, 1), (x - 2, 1)] sage: expand(F) -5*x^2 + 25*x - 30 sage: len(F) 3
On the other hand, -1 is a unit in
, so it is included in the unit.
sage: x = ZZ['x'].0 sage: f = -1*(x-2)*(x-3) sage: F = f.factor(); F (-1) * (x - 3) * (x - 2) sage: F.unit() -1 sage: list(F) [(x - 3, 1), (x - 2, 1)]
Factorizations can involve fairly abstract mathematical objects:
sage: F = ModularSymbols(11,4).factorization() sage: F (Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) * (Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) * (Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) sage: type(F) <class 'sage.structure.factorization.Factorization'>
TESTS:
sage: F = factor(-20); F -1 * 2^2 * 5 sage: G = loads(dumps(F)); G -1 * 2^2 * 5 sage: G == F True sage: G is F False
Author Log:
Class: Factorization
sage: N = 2006 sage: F = N.factor(); F 2 * 17 * 59 sage: F.unit() 1 sage: F = factor(-2006); F -1 * 2 * 17 * 59 sage: F.unit() -1 sage: loads(F.dumps()) == F True sage: F = Factorization([(x,1/3)]) Traceback (most recent call last): ... TypeError: powers of factors must be integers
self, x, [unit=None], [cr=False], [sort=True], [simplify=True]) |
Create a Factorization
object.
Input:
We create a factorization with all the default options:
sage: Factorization([(2,3), (5, 1)]) 2^3 * 5
We create a factorization with a specified unit part:
sage: Factorization([(2,3), (5, 1)], unit=-1) -1 * 2^3 * 5
We try to create a factorization but with a string an exponent, which results in a TypeError:
sage: Factorization([(2,3), (5, 'x')]) Traceback (most recent call last): ... TypeError: powers of factors must be integers
We create a factorization that puts newlines after each multiply sign when printing. This is mainly useful when the primes are large.
sage: Factorization([(2,3), (5, 2)], cr=True) 2^3 * 5^2
Another factorization with newlines and nontrivial unit part (which appears on a line by itself):
sage: Factorization([(2,3), (5, 2)], cr=True, unit=-2) -2 * 2^3 * 5^2
A factorization, but where we do not sort the factors:
sage: Factorization([(5,3), (2, 3)], sort=False) 5^3 * 2^3
By default factorizations are sorted by the prime base (for commutative bases):
sage: Factorization([(2, 7), (5,2), (2, 5)]) 2^12 * 5^2 sage: R.<a,b> = FreeAlgebra(QQ,2) sage: Factorization([(a,1),(b,1),(a,2)]) a * b * a^2
Autosorting (the default) swaps around the factors below:
sage: F = Factorization([(ZZ^3, 2), (ZZ^2, 5)], cr=True); F (Ambient free module of rank 2 over the principal ideal domain Integer Ring)^5 * (Ambient free module of rank 3 over the principal ideal domain Integer Ring)^2
Functions: base_ring,
expand,
is_commutative,
prod,
simplify,
sort,
unit,
unit_part,
value
self) |
Return the parent structure of my factors.
sage: F = factor(2006) sage: F.base_ring() Integer Ring
sage: R.<x,y,z> = FreeAlgebra(QQ, 3) sage: F = Factorization([(z, 2)], 3) sage: (F*F^-1).base_ring() Rational Field
self) |
Same as self.value()
, so this returns the product of
the factors, multiplied out.
sage: x = polygen(QQ, 'x') sage: F = factor(-x^5 + 1); F (-1) * (x - 1) * (x^4 + x^3 + x^2 + x + 1) sage: F.expand() -x^5 + 1
self) |
Return True if my factors commute.
sage: F = factor(2006) sage: F.is_commutative() True sage: K = QuadraticField(23, 'a') sage: F = K.factor(13) sage: F.is_commutative() True sage: R.<x,y,z> = FreeAlgebra(QQ, 3) sage: F = Factorization([(z, 2)], 3) sage: F.is_commutative() False sage: (F*F^-1).is_commutative() True
self) |
Same as self.value()
.
sage: F = factor(100) sage: F.prod() 100
self) |
Combine adjacent products that commute as much as possible.
TESTS:
sage: R.<x,y> = FreeAlgebra(ZZ, 2) sage: F = Factorization([(x,3), (y, 2), (y,2)], simplify=False); F x^3 * y^2 * y^2 sage: F.simplify(); F x^3 * y^4 sage: F * Factorization([(y, -2)], 2) (2) * x^3 * y^2
self, [_cmp=None]) |
Sort the factors in this factorization.
Input:
If _cmp is None, we determine the comparison function as follows: If the prime in the first factor has a dimension method, then we sort based first on dimension then on the exponent. If there is no dimension method, we next attempt to sort based on a degree method, in which case, we sort based first on degree, then exponent to break ties when two factors have the same degree, and if those match break ties based on the actual prime itself. If there is no degree method, we sort based on dimension.
We create a factored polynomial:
sage: x = polygen(QQ,'x') sage: F = factor(x^3 + 1); F (x + 1) * (x^2 - x + 1)
Then we sort it but using the negated version of the standard Python cmp function:
sage: F.sort(_cmp = lambda x,y: -cmp(x,y)) sage: F (x^2 - x + 1) * (x + 1)
self) |
Return the unit part of this factorization.
sage: F = factor(-2006); F -1 * 2 * 17 * 59 sage: F.unit() -1
self) |
Same as self.unit()
.
We create a polynomial over the real double field and factor it:
sage: x = polygen(RDF, 'x') sage: F = factor(-2*x^2 - 1); F (-2.0) * (1.0*x^2 + 0.5)
Note that the unit part of the factorization is
.
sage: F.unit_part() -2.0
self) |
Return the product of the factors in the factorization, multiplied out.
sage: F = factor(2006); F 2 * 17 * 59 sage: F.value() 2006
sage: R.<x,y> = FreeAlgebra(ZZ, 2) sage: F = Factorization([(x,3), (y, 2), (x,1)]); F x^3 * y^2 * x sage: F.value() x^3*y^2*x
Special Functions: __add__,
__cmp__,
__copy__,
__deepcopy__,
__getitem__,
__init__,
__invert__,
__len__,
__mul__,
__neg__,
__pow__,
__rmul__,
__setitem__,
__sub__,
_cr,
_latex_,
_repr_,
_set_cr
self, other) |
Return the sum of self and other.
sage: factor(-10) + 16 6 sage: factor(10) - 16 -6 sage: factor(100) + factor(19) 119
self, other) |
Compare self and other. This compares the underlying lists of self and other (ignoring the unit!)
We compare two contrived formal factorizations:
sage: a = Factorization([(2, 7), (5,2), (2, 5)]) sage: b = Factorization([(2, 7), (5,10), (7, 3)]) sage: a 2^12 * 5^2 sage: b 2^7 * 5^10 * 7^3 sage: a < b True sage: b < a False sage: a.expand() 102400 sage: b.expand() 428750000000
We compare factorizations of some polynomials:
sage: x = polygen(QQ) sage: x^2 - 1 > x^2 - 4 True sage: factor(x^2 - 1) > factor(x^2 - 4) True
self) |
Return a copy of self.
This is of course not a deepcopy - only references to the
factors are returned, not copies of them. Use
deepcopy(self)
if you need a deep copy of self.
We create a factorization that has mutable primes:
sage: F = Factorization([([1,2], 5), ([5,6], 10)]); F ([1, 2])^5 * ([5, 6])^10
We make a copy of it:
sage: G = copy(F); G ([1, 2])^5 * ([5, 6])^10 sage: G is F False
Note that if we change one of the mutable "primes" of F, this does change G.
sage: F[1][0][0] = 'hello' sage: G ([1, 2])^5 * (['hello', 6])^10
self, memo) |
Return a deep copy of self.
This is of course not a deepcopy - only references to the factors are returned, not copies of them.
We make a factorization that has mutable entries:
sage: F = Factorization([([1,2], 5), ([5,6], 10)]); F ([1, 2])^5 * ([5, 6])^10
Now we make a copy of it and a deep copy.
sage: K = copy(F) sage: G = deepcopy(F); G ([1, 2])^5 * ([5, 6])^10
We change one of the mutable entries of F:
sage: F[0][0][0] = 10
This of course changes F:
sage: F ([10, 2])^5 * ([5, 6])^10
It also changes the copy K of F:
sage: K ([10, 2])^5 * ([5, 6])^10
It does not change the deep copy G:
sage: G ([1, 2])^5 * ([5, 6])^10
self, i) |
Return i-th factor of self.
sage: a = factor(-75); a -1 * 3 * 5^2 sage: a[0] (3, 1) sage: a[1] (5, 2) sage: a[-1] (5, 2) sage: a[5] Traceback (most recent call last): ... IndexError: list index out of range
self) |
Return the formal inverse of the factors in the factorization.
sage: F = factor(2006); F 2 * 17 * 59 sage: F^-1 2^-1 * 17^-1 * 59^-1
sage: R.<x,y> = FreeAlgebra(QQ, 2) sage: F = Factorization([(x,3), (y, 2), (x,1)], 2); F (2) * x^3 * y^2 * x sage: F^-1 (1/2) * x^-1 * y^-2 * x^-3
self) |
Return the number of prime factors of self, not counting the unit part.
sage: len(factor(15)) 2
Note that the unit part is not included in the count.
sage: a = factor(-75); a -1 * 3 * 5^2 sage: len(a) 2 sage: list(a) [(3, 1), (5, 2)] sage: len(list(a)) 2
self, other) |
Return the product of two factorizations, which is obtained by combining together like factors.
sage: factor(-10) * factor(-16) 2^5 * 5 sage: factor(-10) * factor(16) -1 * 2^5 * 5
sage: R.<x,y> = FreeAlgebra(ZZ, 2) sage: F = Factorization([(x,3), (y, 2), (x,1)]); F x^3 * y^2 * x sage: F*F x^3 * y^2 * x^4 * y^2 * x sage: -1 * F -1 * x^4 * y^2
self) |
Return negative of this factorization.
sage: a = factor(-75); a -1 * 3 * 5^2 sage: -a 3 * 5^2 sage: (-a).unit() 1
self, n) |
Return the
-th power of a factorization, which is got by
combining together like factors.
sage: f = factor(-100); f -1 * 2^2 * 5^2 sage: f^3 -1 * 2^6 * 5^6 sage: f^4 2^8 * 5^8
sage: F = factor(2006); F 2 * 17 * 59 sage: F**2 2^2 * 17^2 * 59^2
sage: R.<x,y> = FreeAlgebra(ZZ, 2) sage: F = Factorization([(x,3), (y, 2), (x,1)]); F x^3 * y^2 * x sage: F**2 x^3 * y^2 * x^4 * y^2 * x
self, left) |
Return the product left * self, where left is not a Factorization.
sage: a = factor(15); a 3 * 5 sage: -2 * a -2 * 3 * 5 sage: a * -2 -2 * 3 * 5 sage: R.<x,y> = FreeAlgebra(QQ,2) sage: f = Factorization([(x,2),(y,3)]); f x^2 * y^3 sage: x * f x^3 * y^3 sage: f * x x^2 * y^3 * x
self, i, v) |
Set the i-th factor of self.
NOT ALLOWED - Factorizations are immutable.
sage: a = factor(-75); a -1 * 3 * 5^2 sage: a[0] = (2,3) Traceback (most recent call last): ... TypeError: 'Factorization' object does not support item assignment
self, other) |
Return the sum of self and other.
sage: factor(-10) + 16 6 sage: factor(10) - 16 -6
self) |
Return whether or not factorizations are printed with carriage returns between factors.
Our first example involves factoring an integer:
sage: F = factor(-93930); F -1 * 2 * 3 * 5 * 31 * 101 sage: F._cr() False sage: F._set_cr(True) sage: F._cr() True
This of course looks funny:
sage: F -1 * 2 * 3 * 5 * 31 * 101
Next we factor a modular symbols space:
sage: F = ModularSymbols(11).factor(); F (Modular Symbols subspace of dimension 1 of ...) * (Modular Symbols subspace of dimension 1 of ...) * (Modular Symbols subspace of dimension 1 of ...)
self) |
Return the LaTeX representation of this factorization.
sage: f = factor(-100); f -1 * 2^2 * 5^2 sage: latex(f) -1 \cdot 2^{2} \cdot 5^{2} sage: f._latex_() '-1 \\cdot 2^{2} \\cdot 5^{2}'
self) |
Return the string representation of this factorization.
sage: f = factor(-100); f -1 * 2^2 * 5^2 sage: f._repr_() '-1 * 2^2 * 5^2'
Note that the default printing of a factorization can be overloaded using the rename method.
sage: f.rename('factorization of -100') sage: f factorization of -100
However _repr_ always prints normally.
sage: f._repr_() '-1 * 2^2 * 5^2'
sage: x = polygen(QQ) sage: Factorization([(x-1,1), (x-2,2)]) (x - 1) * (x - 2)^2
self, cr) |
Change whether or not the factorization is printed with carriage returns after each factor.
sage: x = polygen(QQ,'x') sage: F = factor(x^6 - 1); F (x - 1) * (x + 1) * (x^2 - x + 1) * (x^2 + x + 1) sage: F._set_cr(True); F (x - 1) * (x + 1) * (x^2 - x + 1) * (x^2 + x + 1) sage: F._set_cr(False); F (x - 1) * (x + 1) * (x^2 - x + 1) * (x^2 + x + 1)
See About this document... for information on suggesting changes.