MonomialIdeal Class

class stdpairs.MonomialIdeal(genset, ambient_monoid)

Bases: object

A class representing a monomial ideal of the given nonzero affine monoid ambient_monoid generated by a set of elements genset as a matrix form.

INPUT:

  • genset – A NumPy.ndarray object with 2-dimensional shape and integer elements or a sage.matrix.matrix_integer_dense object. All columns in genset must lie in ambient_monoid.

  • ambient_monoid – An AffineMonoid object.

OUTPUT:

  • A MonomialIdeal object representing a monomial ideal of an affine semigroup whose generating set is genset.

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q=AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: import numpy
sage: #Using ``NumPy``
sage: M = numpy.array([[4,6],[4,6]])
sage: I = MonomialIdeal(M,Q)
sage: I
An ideal whose generating set is
[[4]
 [4]]
sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q=AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: #Using ``sage.matrix.matrix_integer_dense``
sage: M = matrix(ZZ,[[4,6],[4,6]])
sage: I = MonomialIdeal(M,Q)
sage: I
An ideal whose generating set is
[[4]
 [4]]

TESTS:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: A = matrix(ZZ,[[0,1,1,0],[0,0,1,1],[1,1,1,1]])
sage: Q = AffineMonoid(A)
sage: I = MonomialIdeal(matrix(ZZ,[[2,2,2],[0,1,2],[2,2,2]]),Q)
sage: I.standard_cover().keys()
dict_keys([(0, 3)])
sage: sorted(I.standard_cover()[(0,3)],key=str)
[([[0], [0], [0]]^T,[[0, 0], [0, 1], [1, 1]]),
 ([[1], [0], [1]]^T,[[0, 0], [0, 1], [1, 1]]),
 ([[1], [1], [1]]^T,[[0, 0], [0, 1], [1, 1]])]
sage: I.irreducible_decomposition()
[An ideal whose generating set is
 [[2 2 2]
  [0 1 2]
  [2 2 2]]]
sage: for face, prime_id in I.associated_primes().items():
....:     if I.multiplicity(face) != I.multiplicity(prime_id):
....:         raise SyntaxError("[Error]: multiplicity() method does not work well. Report it to the developer.")
sage: if (I.is_prime() != False) or (I.is_radical() != False) or (I.is_primary() != True):
....:     raise SyntaxError("[Error]: the boolean methods does not work well. Report it to the developer.")
ambient_monoid()

returns the ambient monoid of self.

OUTPUT:

  • An AffineMonoid object.

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q=AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I=MonomialIdeal(matrix(ZZ,[[4,6],[4,6]]),Q)
sage: I.ambient_monoid()
An affine semigroup whose generating set is
[[1 2]
 [0 2]]
associated_primes()

returns a dictionary whose keys are tuples representing faces of self.ambient_monoid and whose values are MonomialIdeal objects which are prime ideals corresponding to the faces in their keys. Notes that this method executes``self.standard_cover()`` if it was not executed previously.

OUTPUT:

  • A dictionary object whose keys are tuple objects representing faces of self.ambient_monoid and whose values are MonomialIdeal objects representing prime monomial ideals corresponding to the faces in their keys.

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q = AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I = MonomialIdeal(matrix(ZZ,[[3],[0]]),Q)
sage: I.associated_primes()
{(1,): An ideal whose generating set is
 [[1]
  [0]]}
gens()

returns the minimal generating matrix of the given monomial ideal. Notes that the generating matrix which was input when the object created is not stored.

OUTPUT:

  • A NumPy.ndarray object with 2-dimensional shape and integer elements

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q=AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I=MonomialIdeal(matrix(ZZ,[[4,6],[4,6]]),Q)
sage: I.gens()
array([[4],
       [4]])
intersect(other)

Given a monomial ideal other, returns the intesection of self and other.

OUTPUT:

  • A MonomialIdeal object representing the intersection of self and other.

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q=AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I=MonomialIdeal(matrix(ZZ,[[3],[2]]),Q)
sage: I.irreducible_decomposition()
[An ideal whose generating set is
 [[1]
  [0]],
 An ideal whose generating set is
 [[2]
  [2]]]
sage: I.irreducible_decomposition()[0].intersect(I.irreducible_decomposition()[1])
An ideal whose generating set is
[[3]
 [2]]
sage: I.irreducible_decomposition()[0].intersect(I.irreducible_decomposition()[1])==I
True
sage: I.irreducible_decomposition()[1].intersect(I.irreducible_decomposition()[0])==I
True
irreducible_decomposition()

returns a list consisting of irreducible ideals such that their intersection is equal to self. Notes that this method executes``self.standard_cover()`` if it was not executed previously.

OUTPUT:

  • A list object consisting of MonomialIdeal objects which are irreducible and their intersection is the same as self.

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q=AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I=MonomialIdeal(matrix(ZZ,[[3],[2]]),Q)
sage: I.irreducible_decomposition()
[An ideal whose generating set is
 [[1]
  [0]],
 An ideal whose generating set is
 [[2]
  [2]]]
sage: I.irreducible_decomposition()[0].intersect(I.irreducible_decomposition()[1]) == I
True
is_element(monomial)

Suppose \(A\) is the generating matrix of the ambient monoid of the given monomial ideal and \(b\) is a vector given by the input monomial. Then this function returns a dictionary object whose keys are integers denoting indices, say \(i\) of column of self.gens(), and whose values are sage.matrix.matrix_integer_dense objects whose row \(u\) satisfies \(A \cdot u^{t}=b-c_{i}\). In other words, if the input is an element of the given monomial ideal, this method returns non-empty dictionary, whose value is a matrix such that rows show how to generated the input using the generators of the affine monoid. Otherwise, if the input is not the element of the given affine monoid, this method returns the empty dictionary.

INPUT:

  • monomial – A NumPy.ndarray object with 2-dimensional shape and integer elements or a sage.matrix.matrix_integer_dense object. This must be a vector; i.e. have one column.

OUTPUT:

  • A dictionary type object whose keys are integers denoting index of columns of self.gens() and whose values are sage.matrix.matrix_integer_dense object whose row \(u\) is the solution of the equation \(A \cdot u^{t}=b-c_{i}\), for given key \(i\) with a column vector \(c_{i}\) of self.gens().

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q=AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I=MonomialIdeal(matrix(ZZ,[[3,7],[2,0]]),Q)
sage: I.is_element(matrix(ZZ,[[9],[2]]))
{0: [6 0], 1: [0 1]}
sage: # In other words, (9,2)^{t} = (3,2)^{t}+6*(1,0)^{t}
sage: # and (9,2)^{t}= (7,0)^{t}+1*(2,2)^{t}
is_empty()

returns True iff it is an empty set as a monomial ideal.

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q=AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I=MonomialIdeal(matrix(ZZ,[[4,6],[4,6]]),Q)
sage: I.is_empty()
False
sage: J=MonomialIdeal(matrix(ZZ,0),Q)
sage: J.is_empty()
True
is_irreducible()

returns True iff it is an irreducible monomial ideal. Notes that this method executes self.standard_cover() if it was not executed previously.

EXAMPLE(Irreducible case):

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: A = matrix(ZZ,[[0,1,1,0],[0,0,1,1],[1,1,1,1]])
sage: Q = AffineMonoid(A)
sage: I = MonomialIdeal(matrix(ZZ,[[2,2,2],[0,1,2],[2,2,2]]),Q)
sage: I.is_irreducible()
True
sage: # After the first execution, it uses the pre-calculated result.
sage: I.is_irreducible()
True

EXAMPLE(Non-irreducible case):

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q=AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I=MonomialIdeal(matrix(ZZ,[[5],[4]]),Q)
sage: I.is_irreducible()
False
is_primary()

returns True iff it is a primary monomial ideal. Notes that this method executes self.standard_cover() if it was not executed previously.

EXAMPLE(Primary case):

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: A = matrix(ZZ,[[1,1],[0,1]])
sage: Q = AffineMonoid(A)
sage: I = MonomialIdeal(matrix(ZZ,[[7],[0]]),Q)
sage: I.is_primary()
True
sage: # After the first execution, it uses the pre-calculated result.
sage: I.is_primary()
True

EXAMPLE(Non-primary case):

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q=AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I=MonomialIdeal(matrix(ZZ,[[5],[4]]),Q)
sage: I.is_primary()
False
is_prime()

returns True iff it is a prime monomial ideal. Notes that this method executes self.standard_cover() if it was not executed previously.

EXAMPLE(Prime case):

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: A = matrix(ZZ,[[1,1],[0,1]])
sage: Q = AffineMonoid(A)
sage: I = MonomialIdeal(matrix(ZZ,[[1],[0]]),Q)
sage: I.is_prime()
True
sage: # After the first execution, it uses the pre-calculated result.
sage: I.is_prime()
True

EXAMPLE(Non-prime case):

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: A = matrix(ZZ,[[1,1],[0,1]])
sage: Q = AffineMonoid(A)
sage: I = MonomialIdeal(matrix(ZZ,[[1,2],[0,2]]),Q)
sage: I.is_prime()
False
is_principal()

returns True iff it is a principal monomial ideal.

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q=AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I=MonomialIdeal(matrix(ZZ,[[4,6],[4,6]]),Q)
sage: I.is_principal()
True
is_radical()

returns True iff it is a radical monomial ideal. Notes that this method executes self.standard_cover() if it was not executed previously.

EXAMPLE(Radical case):

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q=AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I=MonomialIdeal(matrix(ZZ,[[3],[2]]),Q)
sage: I.is_radical()
True
sage: # After the first execution, it uses the pre-calculated result.
sage: I.is_radical()
True

EXAMPLE(Non-radical case):

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q=AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I=MonomialIdeal(matrix(ZZ,[[6,5],[2,2]]),Q)
sage: I.is_radical()
False
is_standard_monomial(monomial)

returns True iff it is a standard monomial, i.e., a monomial outside of the ideal.

EXAMPLE(Radical case):

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q=AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I=MonomialIdeal(matrix(ZZ,[[3],[2]]),Q)
sage: I.is_standard_monomial(matrix(ZZ,[[1],[1]]))
True
sage: #(1,1)^t is not a memeber of ideal.
maximal_overlap_classes()

returns a dictionary whose keys are tuple objects representing faces of self.ambient_monoid() and whose values are list objects consisting of list objects containing standard pairs within the same overlap classes, whchs are maximal with respect to divisibility. Here, divisibility means that for given two overlap classes \([a,F],[b,G]\), \([a,F]<[b,G]\) if there exists \(c\) in the affine monoid such that \(a+c+\mathbb{N}F \subseteq b+\mathbb{N}G\). See [MY2020] for the mathematical definition of overlap classes of standard pairs. Notes that this method executes``self.standard_cover()`` if it was not executed previously.

OUTPUT:

  • A dictionary object whose keys are tuple objects representing faces of self.ambient_monoid and whose values are list objects consisting of list objects representing an overlap class. This list consists of ProperPair objects in the same maximal overlap classes.

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q=AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I=MonomialIdeal(matrix(ZZ,[[3,4],[0,2]]),Q)
sage: I.overlap_classes()
{(): [[([[2], [0]]^T,[[], []])]],
 (1,): [[([[0], [0]]^T,[[2], [2]])], [([[1], [0]]^T,[[2], [2]])]]}
sage: I.maximal_overlap_classes()
{(): [[([[2], [0]]^T,[[], []])]], (1,): [[([[1], [0]]^T,[[2], [2]])]]}
multiplicity(an_ideal_or_face)

Given an associated prime ideal or face (as a tuple object) corresponding to an associated prime ideal, returns the multiplicity of the prime ideal over the given monomial ideal self. Notes that this method executes``self.standard_cover()`` if it was not executed previously.

OUTPUT:

  • A non-negative integer denoting the multiplicity of the given associated prime over the monomial ideal self.

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q = AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I = MonomialIdeal(matrix(ZZ,[[3],[0]]),Q)
sage: I.associated_primes()
{(1,): An ideal whose generating set is
 [[1]
  [0]]}
sage: # Check multiplicity using a face as an argument.
sage: I.multiplicity((1,))
3
sage: # Check multiplicity using the prime ideal as an argument.
sage: I.multiplicity(I.associated_primes()[(1,)])
3
overlap_classes()

returns a dictionary whose keys are tuple objects representing faces of self.ambient_monoid() and whose values are list objects consisting of list objects containing standard pairs within the same overlap classes. See [MY2020] for the mathematical definition of overlap classes of standard pairs. Notes that this method executes``self.standard_cover()`` if it was not executed previously.

OUTPUT:

  • A dictionary object whose keys are tuple objects representing faces of self.ambient_monoid and whose values are list objects consisting of list objects representing an overlap class. This list consists of ProperPair objects in the same overlap classes.

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: A = matrix(ZZ,[[0,1,1,0],[0,0,1,1],[1,1,1,1]])
sage: Q = AffineMonoid(A)
sage: I = MonomialIdeal(matrix(ZZ,[[2,2,2],[0,1,2],[2,2,2]]),Q)
sage: I.overlap_classes().keys()
dict_keys([(0, 3)])
sage: len(I.overlap_classes()[(0,3)])
2
sage: sorted(I.overlap_classes()[(0,3)][0],key=str)
[([[0], [0], [0]]^T,[[0, 0], [0, 1], [1, 1]])]
sage: sorted(I.overlap_classes()[(0,3)][1],key=str)
[([[1], [0], [1]]^T,[[0, 0], [0, 1], [1, 1]]),
 ([[1], [1], [1]]^T,[[0, 0], [0, 1], [1, 1]])]
sage: #Notes that two overlap classes are generated from three standard pairs.
radical()

returns the radical of self as a MonomialIdeal object. Notes that this method executes``self.standard_cover()`` if it was not executed previously.

OUTPUT:

  • A MonomialIdeal object which is radical of the given ideal self.

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: A = matrix(ZZ,[[1,2],[0,2]])
sage: Q = AffineMonoid(A)
sage: I = MonomialIdeal(matrix(ZZ,[[5],[4]]),Q)
sage: I.radical()
An ideal whose generating set is
[[3]
 [2]]
save(path_of_file)

saves the given MonomialIdeal object as sobj file. All previous calculations using self.standard_coveer() is also saved. See Object Persistence for detail.

INPUT:

  • path_of_file – A string object denoting the path which the object self will be saved as a binary file.

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: from pathlib import Path
sage: A = matrix(ZZ,[[0,1,1,0],[0,0,1,1],[1,1,1,1]])
sage: Q = AffineMonoid(A)
sage: I = MonomialIdeal(matrix(ZZ,[[2,2,2],[0,1,2],[2,2,2]]),Q)
sage: I.associated_primes()
{(0,
  3): An ideal whose generating set is
 [[1 1]
  [0 1]
  [1 1]]}
sage: I = loads(dumps(I))
sage: I.associated_primes()
{(0,
  3): An ideal whose generating set is
 [[1 1]
  [0 1]
  [1 1]]}
sage: #The object remember pre-calculated results so that it does not calculate again.
save_txt()

returns a string object containing information about the given monomial ideal and its properties calculated previously. One can recover it using txt_to_monomialideal() method.

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: A = matrix(ZZ,[[1,2],[0,2]])
sage: Q = AffineMonoid(A)
sage: I = MonomialIdeal(matrix(ZZ,[[5],[4]]),Q)
sage: I.standard_cover()[(1,)]
[([[0], [0]]^T,[[2], [2]])]
sage: I.standard_cover()[(0,)]
[([[0], [0]]^T,[[1], [0]]), ([[2], [2]]^T,[[1], [0]])]
sage: sorted(I.standard_cover().keys(),key=str)
[(0,), (1,)]
sage: I.save_txt()
'I\nQ\n1,2|0,2\nis_empty_ideal\n0\ngens\n5|4\n__is_std_cover_calculated\n1\n{"(1,)": ["0|0&(1,)"], "(0,)": ["0|0&(0,)", "2|2&(0,)"]}\n__is_overlap_calculated\n0\n__is_max_overlap_calculated\n0\n__is_ass_prime_calculated\n0\n__is_irr_decom_prime_calculated\n0\n'
standard_cover(verbose=False)

returns a dictionary whose keys are tuple objects representing faces of self.ambient_monoid() and whose values are list objects containing standard pairs of self sharing the same faces. See [MY2020] for the mathematical definition of standard pair. Depending on machines and the number of generators of ideals or affine monoid, this method takes a few minutes to a few hours. Notes that it does not show the status if the given monomial ideal is principal.

If verbose is True, then the function let user knows its progress on computation by showing how many generators are computed.

OUTPUT:

  • A dictionary object whose keys are tuple objects representing faces of self.ambient_monoid and whose values are list objects consisting of ProperPair objects sharing the same face.

Below is an example for finding standard cover of a principal monomial ideal.

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q = AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I = MonomialIdeal(matrix(ZZ,[[4,6],[4,6]]),Q)
sage: I.standard_cover()
{(0,): [([[0], [0]]^T,[[1], [0]]), ([[2], [2]]^T,[[1], [0]])]}

Below is an example for finding standard cover of a non-principal monomial ideal when verbose=True.

EXAMPLE:

sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: Q = AffineMonoid(matrix(ZZ,[[1,2],[0,2]]))
sage: I = MonomialIdeal(matrix(ZZ,[[4,3],[4,2]]),Q)
sage: I.standard_cover(True)[(0,)]
Calculate the standard cover of an ideal
It takes a few minutes, depending on the system.
Cover for 1  generator was calculated.  1  generators remaining.
Cover for 2  generators was calculated.  0  generators remaining.
[([[0], [0]]^T,[[1], [0]])]
sage: I.standard_cover()[()]
[([[2], [2]]^T,[[], []])]
sage: sorted(I.standard_cover().keys(),key=str)
[(), (0,)]

Below is an example for comparing standardPairs function in Macaulay2 and that of self.standard_cover()

EXAMPLE:

sage: print("test MonomialIdeal.standard_cover() . . . .")
test MonomialIdeal.standard_cover() . . . .
sage: from stdpairs import AffineMonoid, MonomialIdeal
sage: import numpy as np
sage: import ast
sage: numvar = 3
sage: numgen = 1
sage: A = np.identity(numvar,dtype="int64")
sage: B = np.random.randint(3, size=(numvar, numgen))
sage: Q = AffineMonoid(A)
sage: I = MonomialIdeal(B,Q)
sage: # Calculate it by Macaulay2
sage: # Set a polynomial ring first.
sage: temp=macaulay2.eval('R=ZZ[vars (0..'+str(numvar-1)+')]')
sage: gens_ideal='I=monomialIdeal(';
sage: for row in I.gens().T:
....:     eq=''
....:     for idx in range(numvar):
....:         eq=eq+'R_'+str(idx)+'^'+str(row[idx])+'*'
....:     eq = eq[:-1]
....:     gens_ideal=gens_ideal + eq+','
sage: gens_ideal=gens_ideal[:-1] + ')'
sage: temp=macaulay2.eval(gens_ideal)
sage: temp=macaulay2.eval('L=standardPairs I')
sage: result=list(macaulay2('T=apply(L, i -> {(exponents i_0)_0, apply(i_1, j -> index j)})'))
sage: for item in result: temp=item[1].sort();
sage: faces = list(set([tuple(item[1]) for item in result]))
sage: faces = [ast.literal_eval(str(face)) for face in faces]
sage: cover_from_mac2={}
sage: for face in faces:
....:     cover_from_mac2[face]=[]
....:     for item in result:
....:         if face == tuple(item[1]):
....:             cover_from_mac2[face].append(ast.literal_eval(str(tuple(item[0]))))
sage: # Calculate standard pairs by stdpairs package
sage: cover_from_sage ={}
sage: for face,list_of_pairs in I.standard_cover().items():
....:     cover_from_sage[face] = [tuple(pair.monomial().T.tolist()[0]) for pair in list_of_pairs]
sage: # Check equality:
sage: faces=list(cover_from_mac2.keys())+list(cover_from_sage.keys())
sage: faces=list(set([str(item) for item in faces]))
sage: faces=[ast.literal_eval(item) for item in faces]
sage: for face in faces:
....:     if set([str(item) for item in cover_from_sage[face]]) != set([str(item) for item in cover_from_mac2[face]]):
....:         raise SyntaxError("Standard pairs from Macaulay2 are not equal to those from stdpairs package.")
sage: print("pass")
pass