#############################################################################
##
#W  semiringmat.xml
#Y  Copyright (C) 2015                                  James D. Mitchell
##
##  Licensing information can be found in the README file of this package.
##
#############################################################################
##

<#GAPDoc Label="AsMatrix">
  <ManSection>
    <Oper Name = "AsMatrix" Arg = "filt, mat"
      Label = "for a filter and a matrix"/>
    <!--  <Oper Name = "AsMatrix" Arg = "semiring, mat"
      Label = "for a semiring and a matrix"/>-->
    <Oper Name = "AsMatrix" Arg = "filt, mat, threshold"
      Label = "for a filter, matrix, and threshold"/>
    <Oper Name = "AsMatrix" Arg = "filt, mat, threshold, period"
      Label = "for a filter, matrix, threshold, and period"/>
    <Returns>A matrix.</Returns>
    <Description>
      This operation can be used to change the representation of certain
      matrices over semirings.  If <A>mat</A> is a matrix over a semiring (in
      the category <Ref Filt = "IsMatrixOverSemiring"/>), then <C>AsMatrix</C>
      returns a new matrix corresponding to <A>mat</A> of the type specified by
      the filter <A>filt</A>, and if applicable the arguments <A>threshold</A>
      and <A>period</A>. The dimension of the matrix <A>mat</A> is not changed
      by this operation.
      <P/>

      The version of the operation with arguments <A>filt</A> and <A>mat</A>
      can be applied to:
      <List>
        <Item>
          <Ref Filt = "IsMinPlusMatrix"/> and a tropical min-plus matrix (i.e.
          convert a tropical min-plus matrix to a (non-tropical) min-plus matrix);
        </Item>
        <Item>
          <Ref Filt = "IsMaxPlusMatrix"/> and a tropical max-plus matrix; <!-- or
          projective max-plus matrix; -->
        </Item>
        <!-- <Item>
          <Ref Filt = "IsProjectiveMaxPlusMatrix"/> and a tropical max-plus
          matrix or (non-tropical) max-plus matrix;
        </Item> -->
      </List>

      The version of the operation with arguments <A>filt</A>, <A>mat</A>, and
      <A>threshold</A> can be applied to:
      <List>
        <Item>
          <Ref Filt = "IsTropicalMinPlusMatrix"/>, a tropical min-plus
          or min-plus matrix, and a value for the threshold of the resulting
          matrix.
        </Item>
        <Item>
          <Ref Filt = "IsTropicalMaxPlusMatrix"/> and a tropical max-plus,
          <!-- projective max-plus, --> or max-plus matrix, and a value for the
          threshold of the resulting matrix.
        </Item>
      </List>

      The version of the operation with arguments <A>filt</A>, <A>mat</A>,
      <A>threshold</A>, and <A>period</A> can be applied to <Ref Filt =
        "IsNTPMatrix"/> and an ntp matrix, or integer matrix.
      <P/>

      When converting matrices with negative entries to an ntp, tropical
      max-plus, or tropical min-plus matrix, the entry is replaced with its
      absolute value.
      <P/>

      When converting non-tropical matrices to tropical matrices entries higher
      than the specified threshold are reduced to the threshold.

      <Example><![CDATA[
gap> mat := Matrix(IsTropicalMinPlusMatrix, [[0, 1, 3],
>                                            [1, 1, 6],
>                                            [0, 4, 2]], 10);;
gap> AsMatrix(IsMinPlusMatrix, mat);
Matrix(IsMinPlusMatrix, [[0, 1, 3], [1, 1, 6], [0, 4, 2]])
gap> mat := Matrix(IsTropicalMaxPlusMatrix, [[-infinity, -infinity, 3],
>                                            [0, 1, 3],
>                                            [4, 1, 0]], 10);;
gap> AsMatrix(IsMaxPlusMatrix, mat);
Matrix(IsMaxPlusMatrix, [[-infinity, -infinity, 3], [0, 1, 3],
  [4, 1, 0]])
gap> mat := Matrix(IsNTPMatrix, [[1, 2, 2],
>                                [0, 2, 0],
>                                [1, 3, 0]], 4, 5);;
gap> Matrix(Integers, mat);
<3x3-matrix over Integers>
gap> mat := Matrix(IsMinPlusMatrix, [[0, 1, 3], [1, 1, 6], [0, 4, 2]]);;
gap> mat := AsMatrix(IsTropicalMinPlusMatrix, mat, 2);
Matrix(IsTropicalMinPlusMatrix, [[0, 1, 2], [1, 1, 2], [0, 2, 2]], 2)
gap> mat := AsMatrix(IsTropicalMinPlusMatrix, mat, 1);
Matrix(IsTropicalMinPlusMatrix, [[0, 1, 1], [1, 1, 1], [0, 1, 1]], 1)
gap> mat := Matrix(IsTropicalMaxPlusMatrix, [[-infinity, -infinity, 3],
>                                            [0, 1, 3],
>                                            [4, 1, 0]], 10);;
gap> AsMatrix(IsTropicalMaxPlusMatrix, mat, 4);
Matrix(IsTropicalMaxPlusMatrix, [[-infinity, -infinity, 3],
  [0, 1, 3], [4, 1, 0]], 4)
gap> mat := Matrix(IsMaxPlusMatrix, [[-infinity, -infinity, 3],
>                                    [0, 1, 3],
>                                    [4, 1, 0]]);;
gap> AsMatrix(IsTropicalMaxPlusMatrix, mat, 10);
Matrix(IsTropicalMaxPlusMatrix, [[-infinity, -infinity, 3],
  [0, 1, 3], [4, 1, 0]], 10)
gap> mat := Matrix(IsNTPMatrix, [[0, 1, 0],
>                                [1, 3, 1],
>                                [1, 0, 1]], 10, 10);;
gap> mat := AsMatrix(IsNTPMatrix, mat, 5, 6);
Matrix(IsNTPMatrix, [[0, 1, 0], [1, 3, 1], [1, 0, 1]], 5, 6)
gap> mat := AsMatrix(IsNTPMatrix, mat, 2, 6);
Matrix(IsNTPMatrix, [[0, 1, 0], [1, 3, 1], [1, 0, 1]], 2, 6)
gap> mat := AsMatrix(IsNTPMatrix, mat, 2, 1);
Matrix(IsNTPMatrix, [[0, 1, 0], [1, 2, 1], [1, 0, 1]], 2, 1)
gap> mat := Matrix(Integers, mat);
<3x3-matrix over Integers>
gap> AsMatrix(IsNTPMatrix, mat, 1, 2);
Matrix(IsNTPMatrix, [[0, 1, 0], [1, 2, 1], [1, 0, 1]], 1, 2)]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="AsList">
  <ManSection>
    <Attr Name = "AsList"        Arg = "mat"/>
    <Oper Name = "AsMutableList" Arg = "mat"/>
    <Returns>A list of lists.</Returns>
    <Description>
      If <A>mat</A> is a matrix over a semiring (in the category <Ref Filt
        = "IsMatrixOverSemiring"/>), then <C>AsList</C> returns the underlying
      list of lists of semiring elements corresponding to <A>mat</A>. In this
      case, the returned list and all of its entries are immutable.
      <P/>

      The operation <C>AsMutableList</C> returns a mutable copy of the
      underlying list of lists of the matrix over semiring <A>mat</A>.

      <Example><![CDATA[
gap> mat := Matrix(IsNTPMatrix,
>                  [[0, 1, 0], [1, 3, 1], [1, 0, 1]], 5, 6);
Matrix(IsNTPMatrix, [[0, 1, 0], [1, 3, 1], [1, 0, 1]], 5, 6)
gap> list := AsList(mat);
[ [ 0, 1, 0 ], [ 1, 3, 1 ], [ 1, 0, 1 ] ]
gap> IsMutable(list);
false
gap> IsMutable(list[1]);
false
gap> list := AsMutableList(mat);
[ [ 0, 1, 0 ], [ 1, 3, 1 ], [ 1, 0, 1 ] ]
gap> IsMutable(list);
true
gap> IsMutable(list[1]);
true
gap> mat = Matrix(IsNTPMatrix, AsList(mat), 5, 6);
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsMatrixOverSemiring">
  <ManSection>
    <Filt Name = "IsMatrixOverSemiring" Arg = "obj" Type = "Category"/>
    <Returns><K>true</K> or <K>false</K>.</Returns>
    <Description>
      Every matrix over a semiring in &SEMIGROUPS; is a member of the category
      <C>IsMatrixOverSemiring</C>, which is a subcategory of
      <Ref Filt = "IsMultiplicativeElementWithOne" BookName = "ref"/>,
      <Ref Filt = "IsAssociativeElement" BookName = "ref"/>, and
      <C>IsPositionalObjectRep</C>; see
      <Ref Sect = "Representation" BookName = "ref"/>.
      <P/>

      Every matrix over a semiring in &SEMIGROUPS; is a square matrix.
      <P/>

      Basic operations for matrices over semirings are:
      <Ref Attr = "DimensionOfMatrixOverSemiring"/>,
      <Ref Attr = "TransposedMat" BookName = "ref"/>, and
      <Ref Attr = "One" BookName = "ref"/>.
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsMatrixOverSemiringCollection">
  <ManSection>
    <Filt Name = "IsMatrixOverSemiringCollection" Arg = "obj" Type = "Category"/>
    <Filt Name = "IsMatrixOverSemiringCollColl" Arg = "obj" Type = "Category"/>
    <Returns><K>true</K> or <K>false</K>.</Returns>
    <Description>
       Every collection of matrices over the same semiring belongs to the
       category <C>IsMatrixOverSemiringCollection</C>. For example, semigroups
       of matrices over a semiring belong to
       <C>IsMatrixOverSemiringCollection</C>. <P/>

       Every collection of collections of matrices over the same semiring
       belongs to the category <C>IsMatrixOverSemiringCollColl</C>.
       For example, a list of semigroups of matrices over semirings belongs
       to <C>IsMatrixOverSemiringCollColl</C>.
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="DimensionOfMatrixOverSemiring">
  <ManSection>
    <Attr Name = "DimensionOfMatrixOverSemiring" Arg = "mat"/>
    <Returns>A positive integer.</Returns>
    <Description>
      If <A>mat</A> is a matrix over a semiring (i.e. belongs to the category
      <Ref Filt = "IsMatrixOverSemiring"/>), then <A>mat</A> is a square <C>n</C>
      by <C>n</C> matrix.
      <C>DimensionOfMatrixOverSemiring</C> returns the dimension <C>n</C> of
      <A>mat</A>.
      <Example><![CDATA[
gap> x := BooleanMat([[1, 0, 0, 1],
>                     [0, 1, 1, 0],
>                     [1, 0, 1, 1],
>                     [0, 0, 0, 1]]);
Matrix(IsBooleanMat, [[1, 0, 0, 1], [0, 1, 1, 0], [1, 0, 1, 1],
  [0, 0, 0, 1]])
gap> DimensionOfMatrixOverSemiring(x);
4]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="DimensionOfMatrixOverSemiringCollection">
  <ManSection>
    <Attr Name = "DimensionOfMatrixOverSemiringCollection" Arg = "coll"/>
    <Returns>A positive integer.</Returns>
    <Description>
      If <A>coll</A> is a collection of matrices over a semiring (i.e. belongs
      to the category <Ref Filt = "IsMatrixOverSemiringCollection"/>), then
      the elements of <A>coll</A> are square <C>n</C> by <C>n</C> matrices.
      <C>DimensionOfMatrixOverSemiringCollection</C> returns the dimension
      <C>n</C> of these matrices.
      <Example><![CDATA[
gap> x := BooleanMat([[1, 0, 0, 1],
>                     [0, 1, 1, 0],
>                     [1, 0, 1, 1],
>                     [0, 0, 0, 1]]);
Matrix(IsBooleanMat, [[1, 0, 0, 1], [0, 1, 1, 0], [1, 0, 1, 1],
  [0, 0, 0, 1]])
gap> DimensionOfMatrixOverSemiringCollection(Semigroup(x));
4]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="Matrix">
  <ManSection>
    <Oper Name = "Matrix" Arg = "filt, mat[, threshold[, period]]"
          Label = "for a filter and a matrix"/>
    <Oper Name = "Matrix" Arg = "semiring, mat"
          Label = "for a semiring and a matrix"/>
    <Returns>A matrix over semiring.</Returns>
    <Description>
      This operation can be used to construct a matrix over
      a semiring in &SEMIGROUPS;.
      <P/>

      In its first form, the first argument <A>filt</A> specifies the
      filter to be used to create the matrix, the second argument <A>mat</A> is
      a &GAP; matrix (i.e. a list of lists) compatible with <A>filt</A>, the
      third and fourth arguments <A>threshold</A> and <A>period</A> (if
      required) must be positive integers.
      <P/>

      <List>
        <Mark><A>filt</A></Mark>
        <Item>
          This must be one of the filters given in
          Section <Ref Sect = "IsXMatrix"/>.
        </Item>

        <Mark><A>mat</A></Mark>
        <Item>
          This must be a list of <C>n</C> lists each of length <C>n</C> (i.e. a
          square matrix), consisting of elements belonging to the underlying
          semiring described by <A>filt</A>, and <A>threshold</A> and
          <A>period</A> if present. An error is given if <A>mat</A> is not
          compatible with the other arguments.
          <P/>

          For example, if <A>filt</A> is <C>IsMaxPlusMatrix</C>, then the
          entries of <A>mat</A> must belong to the max-plus semiring, i.e. they
          must be integers or -<M>\infty</M>. <P/>

          The supported semirings are fully described at the start of this
          chapter.
        </Item>

        <Mark><A>threshold</A></Mark>
        <Item>
          If <A>filt</A> is any of <Ref Filt = "IsTropicalMaxPlusMatrix"/>,
          <Ref Filt = "IsTropicalMinPlusMatrix"/>, or <Ref Filt =
            "IsNTPMatrix"/>, then this argument specifies the threshold of the
          underlying semiring of the matrix being created.
        </Item>

        <Mark><A>period</A></Mark>
        <Item>
          If <A>filt</A> is <Ref Filt = "IsNTPMatrix"/>, then this argument
          specifies the period of the underlying semiring of the matrix being
          created.
        </Item>
      </List>

      In its second form, the arguments should be a semiring <A>semiring</A>
      and matrix <A>mat</A> with entries in <A>semiring</A>. Currently, the
      only supported semirings are finite fields of prime order, and the
      integers <Ref Var = "Integers" BookName = "ref"/>.
      <P/>

      The function <Ref Func = "BooleanMat"/> is provided for specifically
      creating boolean matrices.
      <Example><![CDATA[
gap> Matrix(IsBooleanMat, [[1, 0, 0, 0],
>                          [0, 0, 0, 0],
>                          [1, 1, 1, 1],
>                          [1, 0, 1, 1]]);
Matrix(IsBooleanMat, [[1, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1],
  [1, 0, 1, 1]])
gap> Matrix(IsMaxPlusMatrix, [[4, 0, -2],
>                             [1, -3, 0],
>                             [5, -1, -4]]);
Matrix(IsMaxPlusMatrix, [[4, 0, -2], [1, -3, 0], [5, -1, -4]])
gap> Matrix(IsMinPlusMatrix, [[-1, infinity],
>                             [1, -1]]);
Matrix(IsMinPlusMatrix, [[-1, infinity], [1, -1]])
gap> Matrix(IsTropicalMaxPlusMatrix, [[3, 2, 4],
>                                     [3, 1, 1],
>                                     [-infinity, 1, 1]],
>           9);
Matrix(IsTropicalMaxPlusMatrix, [[3, 2, 4], [3, 1, 1],
  [-infinity, 1, 1]], 9)
gap> Matrix(IsTropicalMinPlusMatrix, [[1, 1, 1],
>                                     [0, 3, 0],
>                                     [1, 1, 3]],
>           9);
Matrix(IsTropicalMinPlusMatrix, [[1, 1, 1], [0, 3, 0], [1, 1, 3]], 9)
gap> Matrix(IsNTPMatrix, [[0, 0, 0],
>                         [2, 0, 1],
>                         [2, 2, 2]],
>           2, 1);
Matrix(IsNTPMatrix, [[0, 0, 0], [2, 0, 1], [2, 2, 2]], 2, 1)
gap> Matrix(Integers, [[-1, -2, 0],
>                      [0, 3, -1],
>                      [1, 0, -3]]);
<3x3-matrix over Integers>
gap> Matrix(Integers, [[-1, -2, 0],
>                      [0, 3, -1],
>                      [1, 0, -3]]);
<3x3-matrix over Integers>
]]></Example>
<!-- Another test, for a matrix over a finite field
gap> Matrix(GF(3), [[Z(3), Z(3) ^ 0, Z(3)],
>                   [Z(3), Z(3) ^ 0, Z(3) ^ 0],
>                   [Z(3), 0 * Z(3), 0 * Z(3)]]);
Matrix(GF(3), [[Z(3), Z(3)^0, Z(3)], [Z(3), Z(3)^0, Z(3)^0],
  [Z(3), 0*Z(3), 0*Z(3)]])
-->
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="RandomMatrix">
  <ManSection>
    <Func Name = "RandomMatrix" Arg = "filt, dim[, threshold[, period]]"
          Label = "for a filter and a matrix"/>
    <Func Name = "RandomMatrix" Arg = "semiring, dim"
          Label = "for a semiring and a matrix"/>
    <Returns>A matrix over semiring.</Returns>
    <Description>
      This operation can be used to construct a random matrix over a semiring
      in &SEMIGROUPS;. The usage of <C>RandomMatrix</C> is similar to that of
        <Ref Oper = "Matrix" Label = "for a filter and a matrix"/>.
      <P/>

      In its first form, the first argument <A>filt</A> specifies the
      filter to be used to create the matrix, the second argument <A>dim</A> is
      dimension of the matrix, the third and fourth arguments <A>threshold</A>
      and <A>period</A> (if required) must be positive integers.
      <P/>

      <List>
        <Mark><A>filt</A></Mark>
        <Item>
          This must be one of the filters given in Section <Ref Sect =
            "IsXMatrix"/>.
        </Item>

        <Mark><A>dim</A></Mark>
        <Item>
          This must be a positive integer.
        </Item>

        <Mark><A>threshold</A></Mark>
        <Item>
          If <A>filt</A> is any of <Ref Filt = "IsTropicalMaxPlusMatrix"/>,
          <Ref Filt = "IsTropicalMinPlusMatrix"/>, or <Ref Filt =
            "IsNTPMatrix"/>, then this argument specifies the threshold of the
          underlying semiring of the matrix being created.
        </Item>

        <Mark><A>period</A></Mark>
        <Item>
          If <A>filt</A> is <Ref Filt = "IsNTPMatrix"/>, then this argument
          specifies the period of the underlying semiring of the matrix being
          created.
        </Item>
      </List>

      In its second form, the arguments should be a semiring <A>semiring</A>
      and dimension <A>dim</A>. Currently, the only supported semirings are
      finite fields of prime order and the integers <Ref Var = "Integers"
        BookName = "ref"/>.

      <Log><![CDATA[
gap> RandomMatrix(IsBooleanMat, 3);
Matrix(IsBooleanMat, [[1, 0, 0], [1, 0, 1], [1, 0, 1]])
gap> RandomMatrix(IsMaxPlusMatrix, 2);
Matrix(IsMaxPlusMatrix, [[1, -infinity], [1, 0]])
gap> RandomMatrix(IsMinPlusMatrix, 3);
Matrix(IsMinPlusMatrix, [[infinity, 2, infinity], [4, 0, -2], [1, -3, 0]])
gap> RandomMatrix(IsTropicalMaxPlusMatrix, 3, 5);
Matrix(IsTropicalMaxPlusMatrix, [[5, 1, 4], [1, -infinity, 1], [1, 0, 2]],
  5)
gap> RandomMatrix(IsTropicalMinPlusMatrix, 3, 2);
Matrix(IsTropicalMinPlusMatrix, [[1, -infinity, -infinity], [1, 1, 1],
  [2, 2, 1]], 2)
gap> RandomMatrix(IsNTPMatrix, 3, 2, 5);
Matrix(IsNTPMatrix, [[1, 1, 1], [1, 1, 0], [3, 0, 1]], 2, 5)
gap> RandomMatrix(Integers, 2);
Matrix(Integers, [[1, 3], [0, 0]])
gap> RandomMatrix(Integers, 2);
Matrix(Integers, [[-1, 0], [0, -1]])
gap> RandomMatrix(GF(5), 1);
Matrix(GF(5), [[Z(5)^0]])]]></Log>
    </Description>
  </ManSection>
<#/GAPDoc>
