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

<#GAPDoc Label="IsXMatrix">
  <ManSection Label = "IsXMatrix">
  <Heading>Matrix filters</Heading>
    <Filt Name = "IsBooleanMat"              Arg = "obj" Type = "Category"/>
    <Filt Name = "IsMatrixOverFiniteField"   Arg = "obj" Type = "Category"/>
    <Filt Name = "IsMaxPlusMatrix"           Arg = "obj" Type = "Category"/>
    <Filt Name = "IsMinPlusMatrix"           Arg = "obj" Type = "Category"/>
    <Filt Name = "IsTropicalMatrix"          Arg = "obj" Type = "Category"/>
    <Filt Name = "IsTropicalMaxPlusMatrix"   Arg = "obj" Type = "Category"/>
    <Filt Name = "IsTropicalMinPlusMatrix"   Arg = "obj" Type = "Category"/>
    <!-- <Filt Name = "IsProjectiveMaxPlusMatrix" Arg = "obj" Type =
         "Category"/> -->
    <Filt Name = "IsNTPMatrix"               Arg = "obj" Type = "Category"/>
    <Filt Name = "Integers"           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 one of these
      categories, which are subcategory of <Ref Filt = "IsMatrixOverSemiring"/>.
      <P/>

      <C>IsTropicalMatrix</C> is a supercategory of
      <C>IsTropicalMaxPlusMatrix</C> and <C>IsTropicalMinPlusMatrix</C>.
      <!-- and <C>IsProjectiveMaxPlusMatrix</C>. -->
      <P/>

      Basic operations for matrices over semirings include: multiplication via
      \*, <Ref Attr = "DimensionOfMatrixOverSemiring"/>, <Ref Attr="One"
        BookName="ref"/>, the underlying list of lists used to create the
      matrix can be accessed using <Ref Attr = "AsList"/>, the rows of
      <C>mat</C> can be accessed using <C>mat[i]</C> where <C>i</C> is between
      <C>1</C> and the dimension of the matrix, it also possible to loop over
      the rows of a matrix; for tropical matrices <Ref
        Attr = "ThresholdTropicalMatrix"/>; for ntp matrices <Ref
        Attr = "ThresholdNTPMatrix"/> and <Ref Attr = "PeriodNTPMatrix"/>.
      <P/>

      For matrices over finite fields see Section 
      <Ref Sect = "Matrices over finite fields"/>; for Boolean matrices more
      details can be found in Section <Ref Sect = "Boolean matrices"/>.

    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsXMatrixCollection">
<ManSection Label = "IsXMatrixCollection">
  <Heading>Matrix collection filters</Heading>
    <Filt Name = "IsBooleanMatCollection"              Arg = "obj" Type =
      "Category"/>
    <Filt Name = "IsBooleanMatCollColl"                Arg = "obj" Type =
      "Category"/>
    <Filt Name = "IsMatrixOverFiniteFieldCollection"   Arg = "obj" Type =
      "Category"/>
    <Filt Name = "IsMatrixOverFiniteFieldCollColl"     Arg = "obj" Type =
      "Category"/>
    <Filt Name = "IsMaxPlusMatrixCollection"           Arg = "obj" Type =
      "Category"/>
    <Filt Name = "IsMaxPlusMatrixCollColl"             Arg = "obj" Type =
      "Category"/>
    <Filt Name = "IsMinPlusMatrixCollection"           Arg = "obj" Type =
      "Category"/>
    <Filt Name = "IsMinPlusMatrixCollColl"             Arg = "obj" Type =
      "Category"/>
    <Filt Name = "IsTropicalMatrixCollection"          Arg = "obj" Type =
      "Category"/>
    <Filt Name = "IsTropicalMaxPlusMatrixCollection"   Arg = "obj" Type =
      "Category"/>
    <Filt Name = "IsTropicalMaxPlusMatrixCollColl"     Arg = "obj" Type =
      "Category"/>
    <Filt Name = "IsTropicalMinPlusMatrixCollection"   Arg = "obj" Type =
      "Category"/>
    <Filt Name = "IsTropicalMinPlusMatrixCollColl"     Arg = "obj" Type =
      "Category"/>
    <!-- <Filt Name = "IsProjectiveMaxPlusMatrixCollection" Arg = "obj" Type =
      "Category"/>
    <Filt Name = "IsProjectiveMaxPlusMatrixCollColl"   Arg = "obj" Type =
      "Category"/> -->
    <Filt Name = "IsNTPMatrixCollection"               Arg = "obj" Type =
      "Category"/>
    <Filt Name = "IsNTPMatrixCollColl"                 Arg = "obj" Type =
      "Category"/>
    <Returns>
      <K>true</K> or <K>false</K>.
    </Returns>
    <Description>
       Every collection of matrices over the same semiring in &SEMIGROUPS;
       belongs to one of the categories above. For example, semigroups of
       boolean matrices belong to <C>IsBooleanMatCollection</C>.
       <P/>

       Similarly, every collection of collections of matrices over the same
       semiring in &SEMIGROUPS; belongs to one of the categories above.
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="ThresholdTropicalMatrix">
  <ManSection>
    <Attr Name="ThresholdTropicalMatrix" Arg="mat"/>
    <Returns>A positive integer.</Returns>
    <Description>
      If <A>mat</A> is a tropical matrix (i.e. belongs to the category <Ref
        Filt = "IsTropicalMatrix"/>), then <C>ThresholdTropicalMatrix</C>
      returns the threshold (i.e. the largest integer) of the underlying
      semiring.
      <Example><![CDATA[
gap> mat := Matrix(IsTropicalMaxPlusMatrix,
> [[0, 3, 0, 2],
>  [1, 1, 1, 0],
>  [-infinity, 1, -infinity, 1],
>  [0, -infinity, 2, -infinity]], 10);
Matrix(IsTropicalMaxPlusMatrix, [[0, 3, 0, 2], [1, 1, 1, 0], 
  [-infinity, 1, -infinity, 1], [0, -infinity, 2, -infinity]], 10)
gap> ThresholdTropicalMatrix(mat);
10
gap> mat := Matrix(IsTropicalMaxPlusMatrix,
> [[0, 3, 0, 2],
>  [1, 1, 1, 0],
>  [-infinity, 1, -infinity, 1],
>  [0, -infinity, 2, -infinity]], 3);
Matrix(IsTropicalMaxPlusMatrix, [[0, 3, 0, 2], [1, 1, 1, 0], 
  [-infinity, 1, -infinity, 1], [0, -infinity, 2, -infinity]], 3)
gap> ThresholdTropicalMatrix(mat);
3]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="ThresholdNTPMatrix">
  <ManSection>
    <Attr Name = "ThresholdNTPMatrix" Arg = "mat"/>
    <Attr Name = "PeriodNTPMatrix" Arg = "mat"/>
    <Returns>A positive integer.</Returns>
    <Description>
      An <B>ntp matrix</B> is a matrix with entries in
      a semiring <M>\mathbb{N}_{t,p} = \{0, 1,
        \ldots, t, t + 1, \ldots, t + p - 1\}</M> for some threshold <M>t</M>
      and period <M>p</M> under addition and multiplication modulo the congruence
      <M>t = t + p</M>.
      <P/>

      If <A>mat</A> is a ntp matrix (i.e. belongs to the category <Ref
        Filt = "IsNTPMatrix"/>), then <C>ThresholdNTPMatrix</C> and
      <C>PeriodNTPMatrix</C> return the threshold and period of the underlying
      semiring, respectively.
      <Example><![CDATA[
gap> mat := Matrix(IsNTPMatrix, [[1, 1, 0],
>                                [2, 1, 0],
>                                [0, 1, 1]],
>                  1, 2);
Matrix(IsNTPMatrix, [[1, 1, 0], [2, 1, 0], [0, 1, 1]], 1, 2)
gap> ThresholdNTPMatrix(mat);
1
gap> PeriodNTPMatrix(mat);
2
gap> mat := Matrix(IsNTPMatrix, [[2, 1, 3],
>                                [0, 5, 1],
>                                [4, 1, 0]],
>                  3, 4);
Matrix(IsNTPMatrix, [[2, 1, 3], [0, 5, 1], [4, 1, 0]], 3, 4)
gap> ThresholdNTPMatrix(mat);
3
gap> PeriodNTPMatrix(mat);
4]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IntInverseOp">
  <ManSection>
    <Oper Name = "InverseOp" Arg = "mat" Label = "for an integer matrix"/>
    <Returns>An integer matrix.</Returns>
    <Description>
      If <A>mat</A> is an integer matrix (i.e. belongs to the category
      <Ref Filt = "Integers"/>) whose inverse (if it exists) is also an
      integer matrix, then <C>InverseOp</C> returns the inverse of <A>mat</A>.
      <P/>

      An integer matrix has an integer matrix inverse if and only if it
      has determinant one.
      <Example><![CDATA[
gap> mat := Matrix(Integers, [[0, 0, -1],
>                             [0, 1, 0],
>                             [1, 0, 0]]);
<3x3-matrix over Integers>
gap> InverseOp(mat);
<3x3-matrix over Integers>
gap> mat * InverseOp(mat) = One(mat);
true
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IntIsTorsion">
  <ManSection>
    <Attr Name = "IsTorsion" Arg = "mat" Label = "for an integer matrix"/>
    <Returns><K>true</K> or <K>false</K></Returns>
    <Description>
      If <A>mat</A> is an integer matrix (i.e. belongs to the
      category <Ref Filt = "Integers"/>), then <C>IsTorsion</C> returns
      <K>true</K> if <A>mat</A> is torsion and <K>false</K> otherwise. <P/>

      An integer matrix <A>mat</A> is torsion if and only if there exists an
      integer <C>n</C> such that <A>mat</A> to the power of <C>n</C> is
      equal to the identity matrix.

      <Example><![CDATA[
gap> mat := Matrix(Integers, [[0, 0, -1],
>                             [0, 1, 0],
>                             [1, 0, 0]]);
<3x3-matrix over Integers>
gap> IsTorsion(mat);
true
gap> mat := Matrix(Integers, [[0, 0, -1, 0],
>                             [0, -1, 0, 0],
>                             [4, 4, 2, -1],
>                             [1, 1, 0, 3]]);
<4x4-matrix over Integers>
gap> IsTorsion(mat);
false
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IntOrder">
  <ManSection>
    <Attr Name = "Order" Arg = "mat"/>
    <Returns>An integer or <C>infinity</C>.</Returns>
    <Description>
      If <A>mat</A> is an integer matrix, then <C>InverseOp</C> returns the
      order of <A>mat</A>. The order of <A>mat</A> is the smallest integer
      power of <A>mat</A> equal to the identity. If no such integer exists, the
      order is equal to <C>infinity</C>.
      <Example><![CDATA[
gap> mat := Matrix(Integers, [[0, 0, -1, 0],
>                             [0, -1, 0, 0],
>                             [4, 4, 2, -1],
>                             [1, 1, 0, 3]]);;
gap> Order(mat);
infinity
gap> mat := Matrix(Integers, [[0, 0, -1],
>                             [0, 1, 0],
>                             [1, 0, 0]]);;
gap> Order(mat);
4
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="SpectralRadius">
  <ManSection>
    <Oper Name = "SpectralRadius" Arg = "mat"/>
    <Returns>A rational number.</Returns>
    <Description>
      If <A>mat</A> is a max-plus matrix (i.e. belongs to the category <Ref
        Filt = "IsMaxPlusMatrix"/>), then <C>SpectralRadius</C>
      returns the supremum of the set of eigenvalues of <A>mat</A>.
      This method is described in <Cite Key="Bacelli1992aa"/>.
      <Example><![CDATA[
gap> SpectralRadius(Matrix(IsMaxPlusMatrix, [[-infinity, 1, -4],
>                                            [2, -infinity, 0],
>                                            [0, 1, 1]]));
3/2]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="InverseOp">
  <ManSection>
    <Oper Name = "InverseOp" Arg = "mat"/>
    <Returns>A max-plus matrix.</Returns>
    <Description>
      If <A>mat</A> is an invertible max-plus matrix (i.e. belongs to the
      category <Ref Filt = "IsMaxPlusMatrix"/> and is a row permutation
      applied to the identity), then <C>InverseOp</C> returns the inverse
      of <A>mat</A>. This method is described in <Cite Key="Kacie2009aa"/>.
      <Example><![CDATA[
gap> InverseOp(Matrix(IsMaxPlusMatrix, [[-infinity, -infinity, 0],
>                                       [0, -infinity, -infinity],
>                                       [-infinity, 0, -infinity]]));
Matrix(IsMaxPlusMatrix, [[-infinity, 0, -infinity], 
  [-infinity, -infinity, 0], [0, -infinity, -infinity]])
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="RadialEigenvector">
  <ManSection>
    <Oper Name = "RadialEigenvector" Arg = "mat"/>
    <Returns>A vector.</Returns>
    <Description>
      If <A>mat</A> is a <C>n</C> by <C>n</C> max-plus matrix (i.e. belongs to
      the category <Ref Filt = "IsMaxPlusMatrix"/>), then
      <C>RadialEigenvector</C> returns an eigenvector corresponding to the
      eigenvalue equal to the spectral radius of <A>mat</A>. This method
      is described in <Cite Key="Kacie2009aa"/>.
      <Example><![CDATA[
gap> RadialEigenvector(Matrix(IsMaxPlusMatrix, [[0, -3], [-2, -10]]));
[ 0, -2 ]
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="UnweightedPrecedenceDigraph">
  <ManSection>
    <Oper Name = "UnweightedPrecedenceDigraph" Arg = "mat"/>
    <Returns>A digraph.</Returns>
    <Description>
      If <A>mat</A> is a max-plus matrix (i.e. belongs to the category <Ref
        Filt = "IsMaxPlusMatrix"/>), then <C>UnweightedPrecedenceDigraph</C>
      returns the unweighted precedence digraph corresponding to <A>mat</A>.
      <P/>

      For an <C>n</C> by <C>n</C> matrix <A>mat</A>, the unweighted precedence
      digraph is defined as the digraph with <C>n</C> vertices where vertex
      <C>i</C> is adjacent to vertex <C>j</C> if and only if
      <A>mat</A><C>[i][j]</C> is not equal to <K>-infinity</K>.
      <Example><![CDATA[
gap> UnweightedPrecedenceDigraph(Matrix(IsMaxPlusMatrix, [[2, -2, 0],
> [-infinity, 10, -2], [-infinity, 2, 1]]));
<immutable digraph with 3 vertices, 7 edges>
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>
