New Upstream Release - gap-design

Ready changes

Summary

Merged new upstream version: 1.8+ds (was: 1.7+ds).

Diff

diff --git a/CHANGES.md b/CHANGES.md
index f02f6c3..846925e 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,15 @@
+Main changes from DESIGN 1.7 to DESIGN 1.8 (February 2023)
+----------------------------------------------------------
+
+1. Added (and documented) the new function OARunMultiplicityBound,
+which gives an upper bound on the multiplicity of any run
+in an orthogonal array or mixed orthogonal array with given
+parameters.
+
+2. Improved the performance of BlockIntersectionPolynomialCheck
+for the important special case of quadratic block intersection
+polynomials. (This used a suggestion of Rhys J. Evans.)
+
 Main changes from DESIGN 1.6 to DESIGN 1.7 (March 2019)
 -------------------------------------------------------
 
diff --git a/PackageInfo.g b/PackageInfo.g
index 396df28..f99b748 100644
--- a/PackageInfo.g
+++ b/PackageInfo.g
@@ -7,8 +7,8 @@ SetPackageInfo( rec(
 
 PackageName := "DESIGN",
 Subtitle := "The Design Package for GAP",
-Version := "1.7",
-Date := "18/03/2019", # dd/mm/yyyy format
+Version := "1.8",
+Date := "20/02/2023", # dd/mm/yyyy format
 License := "GPL-2.0-or-later",
 
 SourceRepository := rec(
@@ -34,7 +34,7 @@ Persons := [
     IsAuthor := true,
     IsMaintainer := true,
     Email := "L.H.Soicher@qmul.ac.uk",
-    WWWHome := "http://www.maths.qmul.ac.uk/~lsoicher/",
+    WWWHome := "https://webspace.maths.qmul.ac.uk/l.h.soicher/",
     Place := "London",
     Institution := Concatenation( [
       "School of Mathematical Sciences, ",
@@ -64,7 +64,7 @@ AcceptDate := "08/2006",
 ##  for a Webpage with more detailed information about the package
 ##  (not more than a few lines, less is ok):
 ##  Please, use '<span class="pkgname">GAP</span>' and
-##  '<span class="pkgname">MyPKG</span>' for specifing package names.
+##  '<span class="pkgname">MyPKG</span>' for specifying package names.
 ##  
 AbstractHTML := "<span class=\"pkgname\">DESIGN</span> is a package for \
 constructing, classifying, partitioning, and studying block designs.",
@@ -147,7 +147,7 @@ TestFile := "tst/testall.g",
 ##  *Optional*: Here you can list some keyword related to the topic 
 ##  of the package.
 # Keywords := ["Smith normal form", "p-adic", "rational matrix inversion"]
-Keywords := ["block design","t-design","design","resolution","efficiency","semi-Latin square","SOMA"]
+Keywords := ["block design","t-design","design","resolution","efficiency","semi-Latin square","SOMA","orthogonal array"]
 
 ));
 
diff --git a/README.md b/README.md
index 2b992a5..979aa5a 100644
--- a/README.md
+++ b/README.md
@@ -4,34 +4,35 @@ The DESIGN Package for GAP
 The DESIGN package is for constructing, classifying, partitioning,
 and studying block designs.
 
-The DESIGN package is Copyright (C) Leonard H. Soicher 2003--2019.  
+The DESIGN package is Copyright (C) Leonard H. Soicher 2003--2023.  
 
 DESIGN is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version. For details, see 
-<http://www.gnu.org/licenses/gpl.html>.
+<https://www.gnu.org/licenses/gpl.html>.
 
 Please reference your use of the DESIGN package in a published work
 as follows:
 
-L.H. Soicher, The DESIGN package for GAP, Version 1.7, 2019,
+L.H. Soicher, The DESIGN package for GAP, Version 1.8, 2023,
 <https://gap-packages.github.io/design>.
 
-Any comments or bug reports should go to <L.H.Soicher@qmul.ac.uk>.
+For questions, remarks, suggestions, and issues, please use the issue
+tracker at <https://github.com/gap-packages/design/issues>.
 
 Installing the DESIGN Package
 -----------------------------
 
 The DESIGN package is included in the standard GAP distribution. You
 only need to download and install DESIGN if you need to install
-the package locally or are installing an upgrade of DESIGN to an
-existing installation of GAP (see the main GAP reference section
-"ref:Installing a GAP Package").  If you do need to download DESIGN,
-you can find archive files for the package in various formats at
-<https://www.gap-system.org/Packages/design.html>, and then your archive
-file of choice should be downloaded and unpacked in the `pkg' subdirectory
-of an appropriate GAP root directory (see the main GAP reference section
+the package locally or are installing an upgrade of DESIGN to
+an existing installation of GAP (see the main GAP reference
+section "ref:Installing a GAP Package"). If you do need to download
+DESIGN, you can find an archive file for the latest release at
+<https://github.com/gap-packages/design/releases>.  This archive
+file can then be downloaded and unpacked in the `pkg' subdirectory of
+an appropriate GAP root directory (see the main GAP reference section
 "ref:GAP Root Directories").
 
 The DESIGN package is written entirely in GAP code, and requires
@@ -42,4 +43,4 @@ fully installed.
 -------------------------------------------------------------------------
 Leonard Soicher,
 Queen Mary University of London,
-March 2019
+February 2023
diff --git a/debian/changelog b/debian/changelog
index 651418e..f109e26 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+gap-design (1.8+ds-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Sun, 19 Mar 2023 00:34:50 -0000
+
 gap-design (1.7+ds-3) unstable; urgency=medium
 
   [Jerome Benoit]
diff --git a/debian/patches/debianization.patch b/debian/patches/debianization.patch
index 75baeb9..0ce3164 100644
--- a/debian/patches/debianization.patch
+++ b/debian/patches/debianization.patch
@@ -6,9 +6,11 @@ Forwarded: not-needed
 Author: Jerome Benoit <calculus@rezozer.net>
 Last-Update: 2019-04-25
 
---- a/PackageInfo.g
-+++ b/PackageInfo.g
-@@ -25,7 +25,7 @@
+Index: gap-design.git/PackageInfo.g
+===================================================================
+--- gap-design.git.orig/PackageInfo.g
++++ gap-design.git/PackageInfo.g
+@@ -25,7 +25,7 @@ ArchiveURL      := Concatenation( ~.Sour
  
  ArchiveFormats := ".tar.gz", 
  
@@ -17,8 +19,10 @@ Last-Update: 2019-04-25
  
  Persons := [
    rec(
---- a/doc/manual.tex
-+++ b/doc/manual.tex
+Index: gap-design.git/doc/manual.tex
+===================================================================
+--- gap-design.git.orig/doc/manual.tex
++++ gap-design.git/doc/manual.tex
 @@ -8,7 +8,7 @@
  %%
  %F  gapmacro . . . . . . . . . . . . . . . .  read the GAP macro package
@@ -28,8 +32,10 @@ Last-Update: 2019-04-25
  %
  %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
---- a/doc/make_doc
-+++ b/doc/make_doc
+Index: gap-design.git/doc/make_doc
+===================================================================
+--- gap-design.git.orig/doc/make_doc
++++ gap-design.git/doc/make_doc
 @@ -4,32 +4,44 @@
  #W  make_doc          make Example Package documentation          Greg Gamble
  ##
diff --git a/doc/design.tex b/doc/design.tex
index 0f8e0a9..9b10f79 100644
--- a/doc/design.tex
+++ b/doc/design.tex
@@ -12,43 +12,47 @@
 
 \Chapter{Design}
 
-This manual describes the {\DESIGN}~1.7 package for {\GAP}.  The {\DESIGN}
+This manual describes the {\DESIGN}~1.8 package for {\GAP}.  The {\DESIGN}
 package is for constructing, classifying, partitioning, and studying
 block designs. 
 
 The {\DESIGN} package is Copyright {\copyright} Leonard H. Soicher
-2003--2019.  {\DESIGN} is part of a wider project, which received EPSRC
+2003--2023.  {\DESIGN} is part of a wider project, which received EPSRC
 funding under grant GR/R29659/01, to provide a web-based resource for
 design theory; see \URL{http://designtheory.org} and \cite{Dotw}.
+The development of {\DESIGN} was also partially supported by EPSRC grant
+EP/M022641/1 (CoDiMa: a Collaborative Computational Project in the area
+of Computational Discrete Mathematics).
 
 {\DESIGN} is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version. For details, see 
-\URL{http://www.gnu.org/licenses/gpl.html}
+\URL{https://www.gnu.org/licenses/gpl.html}.
 
 Please reference your use of the {\DESIGN} package in a published work
 as follows:
 
-L.H.~Soicher, The DESIGN package for GAP, Version 1.7, 2019,
+L.H.~Soicher, The DESIGN package for GAP, Version 1.8, 2023,
 \URL{https://gap-packages.github.io/design}.
 
-Any comments or bug reports should go to
-\Mailto{L.H.Soicher@qmul.ac.uk}.
+For questions, remarks, suggestions, and issues, please use the issue
+tracker at \URL{https://github.com/gap-packages/design/issues}.
+
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \Section{Installing the DESIGN Package}
 
-The {\DESIGN} package is included in the standard {\GAP}
-distribution. You only need to download and install {\DESIGN} if you need
-to install the package locally or are installing an upgrade of {\DESIGN}
-to an existing installation of {\GAP} (see the main {\GAP} reference
+The {\DESIGN} package is included in the standard {\GAP} distribution. You
+only need to download and install {\DESIGN} if you need to install
+the package locally or are installing an upgrade of {\DESIGN} to
+an existing installation of {\GAP} (see the main {\GAP} reference
 section "ref:Installing a GAP Package").  If you do need to download
-{\DESIGN}, you can find archive files for the package in various formats
-at \URL{http://www.gap-system.org/Packages/design.html}, and then your
-archive file of choice should be downloaded and unpacked in the `pkg'
-subdirectory of an appropriate GAP root directory (see the main {\GAP}
-reference section "ref:GAP Root Directories").
+{\DESIGN}, you can find an archive file for the latest release at
+\URL{https://github.com/gap-packages/design/releases}.  This archive
+file can then be downloaded and unpacked in the `pkg' subdirectory of
+an appropriate {\GAP} root directory (see the main {\GAP} reference section
+"ref:GAP Root Directories").
 
 The {\DESIGN} package is written entirely in {\GAP} code, and requires
 no further installation.  However, {\DESIGN} makes use of the {\GRAPE}
@@ -58,7 +62,6 @@ package \cite{Grape}, which must be fully installed.
 \Section{Loading DESIGN}
 
 Before using {\DESIGN} you must load the package within {\GAP} by calling 
-the statement
 
 \begintt
 LoadPackage("design");
diff --git a/doc/manual.bib b/doc/manual.bib
index 133a57f..1b479a7 100644
--- a/doc/manual.bib
+++ b/doc/manual.bib
@@ -50,7 +50,7 @@ journal	= "Discrete Math.",
 volume  = "306",
 year    = "2006",
 pages   = "3014--3027", 
-note	= "\URL{http://dx.doi.org/10.1016/j.disc.2004.10.027}",
+note	= "\URL{https://doi.org/10.1016/j.disc.2004.10.027}",
 }
 
 @article{BaCh,
@@ -92,7 +92,7 @@ journal	= "Bull. London Math. Soc.",
 volume  = "39",
 year    = "2007",
 pages   = "559--564", 
-note	= "\URL{http://dx.doi.org/10.1112/blms/bdm034}",
+note	= "\URL{https://doi.org/10.1112/blms/bdm034}",
 }
 
 @article{McSo,
@@ -102,7 +102,7 @@ journal	= "European J. Combinatorics",
 volume  = "28",
 year    = "2007",
 pages   = "567--571",
-note    = "\URL{http://dx.doi.org/10.1016/j.ejc.2005.02.003}",
+note    = "\URL{https://doi.org/10.1016/j.ejc.2005.02.003}",
 }
 
 @article{Soi1,
@@ -113,13 +113,13 @@ journal	= "J. Comb. Theory, Ser. A",
 volume  = "117",
 year    = "2010",
 pages   = "799--809",
-note    = "\URL{http://dx.doi.org/10.1016/j.jcta.2010.03.005}",
+note    = "\URL{https://doi.org/10.1016/j.jcta.2010.03.005}",
 }
 
 @manual{Grape,
 author       = "L.~H. Soicher",
-title        = "The GRAPE package for GAP, Version 4.8.2",
-year         = "2019",
+title        = "The GRAPE package for GAP, Version 4.9.0",
+year         = "2023",
 note         =  "\URL{https://gap-packages.github.io/grape}",
 }
 
@@ -158,6 +158,6 @@ journal = "J. Symbolic Comput.",
 volume = "60",
 pages = "94--112",
 year = "2014",
-doi = "http://dx.doi.org/10.1016/j.jsc.2013.09.003",
+doi = "https://doi.org/10.1016/j.jsc.2013.09.003",
 }
 
diff --git a/doc/parameters.tex b/doc/parameters.tex
index 66034d1..60e7d99 100644
--- a/doc/parameters.tex
+++ b/doc/parameters.tex
@@ -9,7 +9,7 @@
 \def\nauty{\it nauty}
 \def\Aut{{\rm Aut}\,}
 \def\x{\times}
-\Chapter{Information from block design parameters}
+\Chapter{Information from design parameters}
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \Section{Information from $t$-design parameters}
@@ -192,6 +192,69 @@ gap> TDesignBlockMultiplicityBound(2,12,4,3);
 2
 \endexample
 
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\Section{Information from (mixed) orthogonal array parameters}
+
+For integers $N,k,s,t$, with $N,k>0$, $s>1$, and $0\le t\le k$, 
+an *orthogonal array* \index{orthogonal array}
+OA$(N,k,s,t)$ is an $N\times k$ array, in which the entries come from a
+set of size $s$ of *symbols*, with the property that in any $N\times t$
+subarray, every possible $t$-tuple of symbols occurs as a row equally
+often (which must be $N/s^t$ times).
+
+For integers $N,k_1,\ldots,k_w,s_1,\ldots,s_w,t$, with
+$w,N,k_1,\ldots,k_w>0$, $s_1,\ldots,s_w>1$, and $0\le t\le k:=k_1+\cdots+k_w$,
+a *mixed orthogonal array* 
+\index{mixed orthogonal array}
+OA$(N,s_1^{k_1},\ldots,s_w^{k_w},t)$ is an $N\times k$
+array, in which the entries in the first
+$k_1$ columns come from a set of symbols of size $s_1$, the entries
+in the next $k_2$ columns come from a set of symbols of size $s_2$,
+and so on, with the property that in any $N\times t$ subarray, every
+possible $t$-tuple of symbols occurs as a row equally often.
+Clearly, a mixed orthogonal array OA$(N,s^k,t)$ is the same thing as an
+orthogonal array OA$(N,k,s,t)$.  
+
+The rows of an orthogonal array or mixed orthogonal array are called *runs*. 
+The *multiplicity* of a run is the number of times it appears as a row
+in the array.
+
+
+\>OARunMultiplicityBound( <N>, <k>, <s>, <t> )
+
+Suppose <N>, <k>, <s>, and <t> are integers, with <N>, <k> positive,
+$<s> > 1$, and $0\le <t>\le <k>$.  Then this function returns an upper
+bound on the multiplicity of any run in an orthogonal array OA$(N,k,s,t)$.
+
+An upper bound on the multiplicity of a run in a mixed orthogonal array
+can be obtained by replacing <k> and <s> by non-empty lists of the same
+length, $w$ say, of positive integers, such that $0\le <t> \le$ `Sum(<k>)',
+and each entry of <s> is at least 2.  Then the function returns an
+upper bound on the multiplicity of any run in a mixed orthogonal array
+OA$(N,s[1]^{k[1]},...,s[w]^{k[w]},t)$.
+
+If the value $0$ is returned, then this implies that an orthogonal array
+or mixed orthogonal array with the given parameters does not exist.
+
+We do not claim that the returned upper bound $m$ is achieved; that
+is, there may well be no (mixed) orthogonal array with the given
+parameters having a run with multiplicity $m$.
+
+\beginexample
+gap> OARunMultiplicityBound(81,14,3,3);
+1
+gap> OARunMultiplicityBound(81,15,3,3);
+0
+gap> OARunMultiplicityBound(36,[18,1,1],[2,3,6],2);
+1
+gap> OARunMultiplicityBound(72,7,6,2);
+2
+gap> OARunMultiplicityBound(72,8,6,2);
+1
+\endexample
+
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \Section{Block intersection polynomials}
 
diff --git a/doc/sls.tex b/doc/sls.tex
index 7dad312..fff94fe 100644
--- a/doc/sls.tex
+++ b/doc/sls.tex
@@ -47,7 +47,7 @@ Let $A$ be an $(n\times n)/k$  semi-Latin square.  Then the dual of $A$
 can be represented as a binary block design as follows. The point-set of
 $D$ is taken to be the Cartesian square of $\{1,\ldots,n\}$, with $[x,y]$
 representing the $[x,y]$-entry of $A$. The blocks of $D$ are in one-to-one
-correspondance with the symbols of $A$, with the $i$-th block of $D$
+correspondence with the symbols of $A$, with the $i$-th block of $D$
 consisting of the ordered pairs $[x,y]$ such that the $i$-th symbol of
 $A$ is contained in the $[x,y]$-entry of $A$. Given $D$, the semi-Latin
 square $A$ can be recovered, up to the naming of its symbols.
diff --git a/doc/tthmacros.tex b/doc/tthmacros.tex
new file mode 100644
index 0000000..3dc1103
--- /dev/null
+++ b/doc/tthmacros.tex
@@ -0,0 +1,8 @@
+\def\Q{{\bf Q}}\def\Z{{\bf Z}}\def\N{{\bf N}}
+\def\R{{\bf R}}\def\F{{\bf F}}
+\def\calR{{\cal R}}\def\I{{\cal I}}
+\def\frac#1#2{{{#1}\over{#2}}}\def\colon{:}
+\def\longmapsto{\mapsto}\def\lneqq{<}
+\def\hookrightarrow{\rightarrow}
+\def\mid{ | }\def\lbrack{[}\def\rbrack{]}
+\def\gets{\leftarrow}\def\land{\wedge}
diff --git a/doc/tthout b/doc/tthout
new file mode 100644
index 0000000..a9e1795
--- /dev/null
+++ b/doc/tthout
@@ -0,0 +1 @@
+sh: 1: tth: not found
diff --git a/doc/xmlio.tex b/doc/xmlio.tex
index 58f7c58..8773aaf 100644
--- a/doc/xmlio.tex
+++ b/doc/xmlio.tex
@@ -101,8 +101,8 @@ element in a string.
 \beginexample
 gap> BlockDesignsFromXMLFile("example.xml");
 rec( 
-  infoXML := "<info>\n<software>\n[ DESIGN-1.7, GRAPE-4.8.2, GAPDoc-1.6.2, GAP\
--4.10.1 ]\n</software>\n</info>", 
+  infoXML := "<info>\n<software>\n[ DESIGN-1.8, GRAPE-4.9.0, GAPDoc-1.6.6, GAP\
+-4.12.1 ]\n</software>\n</info>", 
   list := 
     [ 
       rec( blocks := [ [ 1, 2 ], [ 1, 3 ] ], id := "example-0", 
diff --git a/lib/blockdesign.g b/lib/blockdesign.g
index 77f0f08..fd980cc 100644
--- a/lib/blockdesign.g
+++ b/lib/blockdesign.g
@@ -1,6 +1,6 @@
 ############################################################################
 ##
-##    blockdesign.g             Design 1.7 Package          Leonard Soicher
+##    blockdesign.g             Design 1.8 Package          Leonard Soicher
 ##
 ##
 # Functions to study, construct and classify (sub)block designs 
@@ -8,7 +8,7 @@
 # block designs with given properties.
 # At present there is limited support for non-binary block designs.
 # 
-# Copyright (C) 2003-2019 Leonard H. Soicher
+# Copyright (C) 2003-2023 Leonard H. Soicher
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -175,7 +175,7 @@ BindGlobal("BlockIntersectionPolynomialCheck",function(m,lambdavec)
 # has a non-negative value whenever x is an integer. 
 # Returns true if all this is so; else false is returned.
 #
-local c,x,B,D,i;
+local c,x,B,D,i,xmin,closestintxmin;
 if not IsList(m) or not IsList(lambdavec) then
    Error("usage: BlockIntersectionPolynomialCheck( <List>, <List> )");
 fi;
@@ -200,8 +200,14 @@ elif c[Length(c)]<0 or c[1]<0 or Length(c) mod 2 = 0 then
    # B has negative leading coef or B(0)<0 or B has odd degree.
    return false;
 elif Length(c)=1 then
-   # B is a constant positive polynomial
+   # B is a constant positive polynomial.
    return true;
+elif Length(c)=3 then
+   # B is a quadratic with positive leading term.
+   # Handle this case as suggested by Rhys Evans.
+   xmin:=-c[2]/(2*c[3]); #  B has minimum value at xmin. 
+   closestintxmin:=BestQuoInt(NumeratorRat(xmin),DenominatorRat(xmin));
+   return Value(B,closestintxmin)>=0;
 fi;
 # Now apply the bound in [Soicher, MCompSci Thesis] to the absolute
 # values of the zeros of B.  See also:  
@@ -892,6 +898,122 @@ fi;
 return blockmultiplicitybound(t,v,k,lambda);
 end);
 
+BindGlobal("OARunMultiplicityBound",function(N,k,s,t)
+#
+# Suppose N is a positive integer, and k and s are non-empty
+# lists of the same length, w say, of positive integers, with 
+# each element of s >1, and t is a non-negative integer <= Sum(k). 
+#
+# Then this function returns an upper bound on the multiplicity of 
+# any run in a (mixed) orthogonal array OA(N,s[1]^k[1],...,s[w]^k[w],t). 
+#
+# If k is given as an integer, it is replaced by [k].
+# If s is given as an integer, it is replaced by [s].
+#
+# The technique used is based on the results in: 
+# P.J. Cameron and L.H. Soicher, Block intersection polynomials, 
+# Bull. London Math. Soc. 39 (2007), 559-564.
+#
+
+local runmultiplicitybound,S,i,j;
+
+runmultiplicitybound:=function(N,S,t)
+#
+# This function does most of the work.
+# S is a nonempty list whose length is the number of factors, and 
+# with S[i] being the size of the symbol set for the i-th factor.
+#
+local lambdavec,m,i,C,c,count,nrtuples,nrfactors,num,
+   symbolsetsizes,maxsymbolsetsize;
+if t=0 then
+   return N;
+fi; 
+nrfactors:=Length(S);
+symbolsetsizes:=Set(S); # the set of the sizes of the symbol sets
+maxsymbolsetsize:=symbolsetsizes[Length(symbolsetsizes)];
+if t=1 then
+   if ForAny(symbolsetsizes,size->N mod size <> 0) then
+      return 0;
+   else
+      return N/maxsymbolsetsize;
+   fi;
+fi;
+# Now Length(S) >= t >= 2. 
+if t mod 2 <> 0 then
+   return Minimum(List(symbolsetsizes,size->
+      runmultiplicitybound(N/size,S{Difference([1..nrfactors],[Position(S,size)])},t-1)));
+fi;
+# Now t>=2 is even, and we determine the bound using
+# block intersection polynomials.
+num:=ListWithIdenticalEntries(maxsymbolsetsize,0);
+for i in [1..nrfactors] do
+   num[S[i]]:=num[S[i]]+1;
+od;
+# So now, num[j] is the number of factors having a symbol set of size j.
+lambdavec:=[N];
+for i in [1..t] do
+   #
+   # determine lambdavec[i+1]
+   #
+   lambdavec[i+1]:=0;
+   C:=Combinations(S,i); # the set of submultisets of S of size i 
+   for c in C do
+      nrtuples:=Product(c);
+      # nrtuples is the number of i-tuples where the first element
+      # is from a symbol set of size c[1], the second from a symbol
+      # set of size c[2], and so on.
+      if N mod nrtuples <> 0 then
+         return 0;
+      fi;
+      count:=Product(Collected(c),x->Binomial(num[x[1]],x[2]));
+      # count is the number of times the multiset  c  occurs over 
+      # all choices of  i  elements from  S.
+      #
+      # Now add in their contribution.
+      # 
+      lambdavec[i+1]:=lambdavec[i+1]+count*(N/nrtuples);
+   od;
+   # Now take the average contribution.
+   lambdavec[i+1]:=lambdavec[i+1]/Binomial(nrfactors,i); 
+od;
+m:=ListWithIdenticalEntries(nrfactors+1,0);
+m[nrfactors+1]:=1;
+while BlockIntersectionPolynomialCheck(m,lambdavec) do
+   m[nrfactors+1]:=m[nrfactors+1]+1;
+od;
+return m[nrfactors+1]-1;
+end;
+
+if IsInt(k) then
+   k:=[k];
+fi;
+if IsInt(s) then
+   s:=[s];
+fi;
+if not (IsInt(N) and IsList(k) and IsList(s) and IsInt(t)) then
+   Error("usage: OARunMultiplicityBound( <Int>, <Int> or <List>, <Int> or <List>, <Int> )");
+fi;
+if N<1 or t<0 then
+   Error("<N> must be positive and <t> must be non-negative");
+fi;
+if Length(s)<>Length(k) or Length(s)=0 then
+   Error("<s> and <k> must have equal positive length");
+fi;
+if ForAny(k,x->not IsPosInt(x)) or t>Sum(k) then
+   Error("<k> must be a list of positive integers, with Sum(<k>) >= <t>");
+fi;
+if ForAny(s,x->not IsInt(x) or x<2) then
+   Error("each element of <s> must be an integer > 1");
+fi;
+S:=[];
+for i in [1..Length(s)] do
+   for j in [1..k[i]] do
+      Add(S,s[i]);
+   od;
+od;
+return runmultiplicitybound(N,S,t);
+end);
+
 BindGlobal("ResolvableTDesignBlockMultiplicityBound",function(t,v,k,lambda)
 
 local multbound,r,lambdavec,m,lower,upper,mid;
diff --git a/lib/blockdesign_io.g b/lib/blockdesign_io.g
index f1e30fa..32cf745 100644
--- a/lib/blockdesign_io.g
+++ b/lib/blockdesign_io.g
@@ -1,6 +1,6 @@
 #############################################################################
 ##
-##    blockdesign_io.g          Design 1.7 Package          Leonard Soicher
+##    blockdesign_io.g          Design 1.8 Package          Leonard Soicher
 ##
 ##    
 # The "GAP Expander/Writer" to expand the information about 
@@ -11,7 +11,7 @@
 # DTRS external representation XML-format, and to convert these 
 # block designs into GAP-format.
 #
-# Copyright (C) 2003-2019 Leonard H. Soicher
+# Copyright (C) 2003-2023 Leonard H. Soicher
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/tst/testall.tst b/tst/testall.tst
index fb505af..9f8526e 100644
--- a/tst/testall.tst
+++ b/tst/testall.tst
@@ -102,6 +102,16 @@ gap> ResolvableTDesignBlockMultiplicityBound(2,12,4,3);
 1
 gap> TDesignBlockMultiplicityBound(2,12,4,3);
 2
+gap> OARunMultiplicityBound(81,14,3,3);
+1
+gap> OARunMultiplicityBound(81,15,3,3);
+0
+gap> OARunMultiplicityBound(36,[18,1,1],[2,3,6],2);
+1
+gap> OARunMultiplicityBound(72,7,6,2);
+2
+gap> OARunMultiplicityBound(72,8,6,2);
+1
 gap> x:=Indeterminate(Rationals,1);
 x_1
 gap> m:=[0,0,0,0,0,0,0,1];;

More details

Full run details

Historical runs