GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#############################################################################
##
#W arithlst.tst GAP library Thomas Breuer
##
##
#Y Copyright (C) 2000, Lehrstuhl D für Mathematik, RWTH Aachen, Germany
##
## Exclude from testinstall.g because it runs too long.
##
gap> START_TEST("arithlst.tst");
#############################################################################
##
## Parametrize the output; if `error' has the value `Error' then only the
## first error in each call is printed in the `Test' run,
## if the value is `Print' then all errors are printed.
##
gap> error:= Print;;
#############################################################################
##
## Define auxiliary functions.
##
gap> RandomSquareArray := function( dim, D )
> return List( [ 1 .. dim ], i -> List( [ 1 .. dim ], j -> Random( D ) ) );
> end;;
gap> NestingDepthATest := function( obj )
> if not IsGeneralizedRowVector( obj ) then
> return 0;
> elif IsEmpty( obj ) then
> return 1;
> else
> return 1 + NestingDepthATest( obj[ PositionBound( obj ) ] );
> fi;
> end;;
gap> NestingDepthMTest := function( obj )
> if not IsMultiplicativeGeneralizedRowVector( obj ) then
> return 0;
> elif IsEmpty( obj ) then
> return 1;
> else
> return 1 + NestingDepthMTest( obj[ PositionBound( obj ) ] );
> fi;
> end;;
gap> ImmutabilityLevel2 := function( list )
> if not IsList( list ) then
> if IsMutable( list ) then
> Error( "<list> is not a list" );
> else
> return 0;
> fi;
> elif IsEmpty( list ) then
> # The empty list is defined to have immutability level 0.
> return 0;
> elif IsMutable( list ) then
> return ImmutabilityLevel2( list[ PositionBound( list ) ] );
> else
> return 1 + ImmutabilityLevel2( list[ PositionBound( list ) ] );
> fi;
> end;;
gap> ImmutabilityLevel := function( list )
> if IsMutable( list ) then
> return ImmutabilityLevel2( list );
> else
> return infinity;
> fi;
> end;;
## Note that the two-argument version of `List' is defined only for
## dense lists.
gap> ListWithPrescribedHoles := function( list, func )
> local result, i;
>
> result:= [];
> for i in [ 1 .. Length( list ) ] do
> if IsBound( list[i] ) then
> result[i]:= func( list[i] );
> fi;
> od;
> return result;
> end;;
gap> SumWithHoles := function( list )
> local pos, result, i;
>
> pos:= PositionBound( list );
> result:= list[ pos ];
> for i in [ pos+1 .. Length( list ) ] do
> if IsBound( list[i] ) then
> result:= result + list[i];
> fi;
> od;
> return result;
> end;;
gap> ParallelOp := function( op, list1, list2, mode )
> local result, i;
>
> result:= [];
> for i in [ 1 .. Maximum( Length( list1 ), Length( list2 ) ) ] do
> if IsBound( list1[i] ) then
> if IsBound( list2[i] ) then
> result[i]:= op( list1[i], list2[i] );
> elif mode = "one" then
> result[i]:= ShallowCopy( list1[i] );
> fi;
> elif IsBound( list2[i] ) and mode = "one" then
> result[i]:= ShallowCopy( list2[i] );
> fi;
> od;
> return result;
> end;;
gap> ErrorMessage := function( opname, operands, info, is, should )
> local str, i;
>
> str:= Concatenation( opname, "( " );
> for i in [ 1 .. Length( operands ) - 1 ] do
> Append( str, operands[i] );
> Append( str, ", " );
> od;
> error( str, operands[ Length( operands ) ], " ): ", info, ",\n",
> "should be ", should, " but is ", is, "\n" );
> end;;
gap> CheckMutabilityStatus := function( opname, list )
> local attr, op, val, sm;
>
> attr:= ValueGlobal( Concatenation( opname, "Attr" ) );
> if ImmutabilityLevel( attr( list ) ) <> infinity then
> error( opname, "Attr: mutability problem for ", list,
> " (", ImmutabilityLevel( list ), ")\n" );
> fi;
> op:= ValueGlobal( Concatenation( opname, "Op" ) );
> val:= op( list );
> if val <> fail and IsCopyable( val ) and not IsMutable( val ) then
> error( opname, "Op: mutability problem for ", list,
> " (", ImmutabilityLevel( list ), ")\n" );
> fi;
> sm:= ValueGlobal( Concatenation( opname, "SM" ) );
> val:= sm( list );
> if val <> fail
> and IsCopyable( val )
> and ImmutabilityLevel( sm( list ) ) <> ImmutabilityLevel( list ) then
> error( opname, "SM: mutability problem for ", list,
> " (", ImmutabilityLevel( list ), ")\n" );
> fi;
> end;;
## Check whether a unary operation preserves the compression status.
gap> COMPRESSIONS := [ "Is8BitMatrixRep", "Is8BitVectorRep",
> "IsGF2VectorRep", "IsGF2MatrixRep" ];;
gap> CheckCompressionStatus := function( opname, list )
> local value, namefilter, filter;
>
> value:= ValueGlobal( opname )( list );
> if value <> fail then
> for namefilter in COMPRESSIONS do
> filter:= ValueGlobal( namefilter );
> if filter( list ) and not filter( value ) then
> error( opname, " does not preserve `", namefilter, "'\n" );
> fi;
> od;
> fi;
> end;;
gap> CompareTest := function( opname, operands, result, desired )
> local i, j, val;
>
> # Check that the same positions are bound,
> # and that corresponding entries are equal.
> if IsList( result ) and IsList( desired ) then
> if Length( result ) <> Length( desired ) then
> ErrorMessage( opname, operands, "lengths differ",
> Length( result ), Length( desired ) );
> fi;
> for i in [ 1 .. Length( result ) ] do
> if IsBound( result[i] ) then
> if not IsBound( desired[i] ) then
> ErrorMessage( opname, operands,
> Concatenation( "bound at ", String( i ) ),
> result[i], "unbound" );
> elif result[i] <> desired[i] then
> ErrorMessage( opname, operands,
> Concatenation( "error at ", String( i ) ),
> result[i], desired[i] );
> fi;
> elif IsBound( desired[i] ) then
> ErrorMessage( opname, operands,
> Concatenation( "unbound at ", String( i ) ),
> "unbound", desired[i] );
> fi;
> od;
> elif IsList( result ) or IsList( desired ) then
> ErrorMessage( opname, operands, "list vs. non-list", result, desired );
> elif result <> desired then
> ErrorMessage( opname, operands, "two non-lists", result, desired );
> fi;
>
> # Check the mutability status.
> if Length( operands ) = 2
> and IsList( result ) and IsCopyable( result )
> and ImmutabilityLevel( result )
> <> Minimum( List( operands, ImmutabilityLevel ) )
> and not (ImmutabilityLevel(result)=infinity and
> NestingDepthM(result) =
> Minimum( List( operands, ImmutabilityLevel ) )) then
> error( opname, ": mutability problem for ", operands[1], " (",
> ImmutabilityLevel( operands[1] ), ") and ", operands[2], " (",
> ImmutabilityLevel( operands[2] ), ")\n" );
> fi;
> end;;
#############################################################################
##
#F ZeroTest( <list> )
##
## The zero of a list $x$ in `IsGeneralizedRowVector' is defined as
## the list whose entry at position $i$ is the zero of $x[i]$
## if this entry is bound, and is unbound otherwise.
##
gap> ZeroTest := function( list )
> if IsGeneralizedRowVector( list ) then
> CompareTest( "Zero", [ list ],
> Zero( list ),
> ListWithPrescribedHoles( list, Zero ) );
> CheckMutabilityStatus( "Zero", list );
> CheckCompressionStatus( "ZeroAttr", list );
> CheckCompressionStatus( "ZeroSM", list );
> fi;
> end;;
#############################################################################
##
#F AdditiveInverseTest( <list> )
##
## The additive inverse of a list $x$ in `IsGeneralizedRowVector' is defined
## as the list whose entry at position $i$ is the additive inverse of $x[i]$
## if this entry is bound, and is unbound otherwise.
##
gap> AdditiveInverseTest := function( list )
> if IsGeneralizedRowVector( list ) then
> CompareTest( "AdditiveInverse", [ list ],
> AdditiveInverse( list ),
> ListWithPrescribedHoles( list, AdditiveInverse ) );
> CheckMutabilityStatus( "AdditiveInverse", list );
> CheckCompressionStatus( "AdditiveInverseAttr", list );
> CheckCompressionStatus( "AdditiveInverseSM", list );
> fi;
> end;;
#############################################################################
##
#F AdditionTest( <left>, <right> )
##
## If $x$ and $y$ are in `IsGeneralizedRowVector' and have the same
## additive nesting depth (see~"NestingDepthA"),
## % By definition, this depth is nonzero.
## the sum $x + y$ is defined *pointwise*, in the sense that the result is a
## list whose entry at position $i$ is $x[i] + y[i]$ if these entries are
## bound,
## is a shallow copy (see~"ShallowCopy") of $x[i]$ or $y[i]$ if the other
## argument is not bound at position $i$,
## and is unbound if both $x$ and $y$ are unbound at position $i$.
##
## If $x$ is in `IsGeneralizedRowVector' and $y$ is either not a list or is
## in `IsGeneralizedRowVector' and has lower additive nesting depth,
## the sum $x + y$ is defined as a list whose entry at position $i$ is
## $x[i] + y$ if $x$ is bound at position $i$, and is unbound if not.
## The equivalent holds in the reversed case,
## where the order of the summands is kept,
## as addition is not always commutative.
##
## For two {\GAP} objects $x$ and $y$ of which one is in
## `IsGeneralizedRowVector' and the other is either not a list or is
## also in `IsGeneralizedRowVector',
## $x - y$ is defined as $x + (-y)$.
##
gap> AdditionTest := function( left, right )
> local depth1, depth2, desired;
>
> if IsGeneralizedRowVector( left ) and IsGeneralizedRowVector( right ) then
> depth1:= NestingDepthATest( left );
> depth2:= NestingDepthATest( right );
> if depth1 = depth2 then
> desired:= ParallelOp( \+, left, right, "one" );
> elif depth1 < depth2 then
> desired:= ListWithPrescribedHoles( right, x -> left + x );
> else
> desired:= ListWithPrescribedHoles( left, x -> x + right );
> fi;
> elif IsGeneralizedRowVector( left ) and not IsList( right ) then
> desired:= ListWithPrescribedHoles( left, x -> x + right );
> elif not IsList( left ) and IsGeneralizedRowVector( right ) then
> desired:= ListWithPrescribedHoles( right, x -> left + x );
> else
> return;
> fi;
> CompareTest( "Addition", [ left, right ], left + right, desired );
> if AdditiveInverse( right ) <> fail then
> CompareTest( "Subtraction", [ left, right ], left - right,
> left + ( - right ) );
> fi;
> end;;
#############################################################################
##
#F OneTest( <list> )
##
gap> OneTest := function( list )
> if IsOrdinaryMatrix( list ) and Length( list ) = Length( list[1] ) then
> CheckMutabilityStatus( "One", list );
> CheckCompressionStatus( "OneAttr", list );
> CheckCompressionStatus( "OneSM", list );
> fi;
> end;;
#############################################################################
##
#F InverseTest( <obj> )
##
gap> InverseTest := function( list )
> if IsOrdinaryMatrix( list ) and Length( list ) = Length( list[1] ) then
> CheckMutabilityStatus( "Inverse", list );
> CheckCompressionStatus( "InverseAttr", list );
> CheckCompressionStatus( "InverseSM", list );
> fi;
> end;;
#############################################################################
##
#F TransposedMatTest( <obj> )
##
gap> TransposedMatTest := function( list )
> if IsOrdinaryMatrix( list ) then
> CheckCompressionStatus( "TransposedMatAttr", list );
> CheckCompressionStatus( "TransposedMatOp", list );
> fi;
> end;;
#############################################################################
##
#F MultiplicationTest( <left>, <right> )
##
## There are three possible computations that might be triggered by a
## multiplication involving a list in
## `IsMultiplicativeGeneralizedRowVector'.
## Namely, $x * y$ might be
## \beginlist
## \item{(I)}
## the inner product $x[1] * y[1] + x[2] * y[2] + \cdots + x[n] * y[n]$,
## where summands are omitted for which the entry in $x$ or $y$ is
## unbound
## (if this leaves no summand then the multiplication is an error),
## or
## \item{(L)}
## the left scalar multiple, i.e., a list whose entry at position $i$ is
## $x * y[i]$ if $y$ is bound at position $i$, and is unbound if not, or
## \item{(R)}
## the right scalar multiple, i.e., a list whose entry at position $i$
## is $x[i] * y$ if $x$ is bound at position $i$, and is unbound if not.
## \endlist
##
## Our aim is to generalize the basic arithmetic of simple row vectors and
## matrices, so we first summarize the situations that shall be covered.
##
## \beginexample
## | scl vec mat
## ---------------------
## scl | (L) (L)
## vec | (R) (I) (I)
## mat | (R) (R) (R)
## \endexample
##
## This means for example that the product of a scalar (scl)
## with a vector (vec) or a matrix (mat) is computed according to (L).
## Note that this is asymmetric.
##
## Now we can state the general multiplication rules.
##
## If exactly one argument is in `IsMultiplicativeGeneralizedRowVector'
## then we regard the other argument (which is then not a list) as a scalar,
## and specify result (L) or (R), depending on ordering.
##
## In the remaining cases, both $x$ and $y$ are in
## `IsMultiplicativeGeneralizedRowVector', and we distinguish the
## possibilities by their multiplicative nesting depths.
## An argument with *odd* multiplicative nesting depth is regarded as a
## vector, and an argument with *even* multiplicative nesting depth is
## regarded as a scalar or a matrix.
##
## So if both arguments have odd multiplicative nesting depth,
## we specify result (I).
##
## If exactly one argument has odd nesting depth,
## the other is treated as a scalar if it has lower multiplicative nesting
## depth, and as a matrix otherwise.
## In the former case, we specify result (L) or (R), depending on ordering;
## in the latter case, we specify result (L) or (I), depending on ordering.
##
## We are left with the case that each argument has even multiplicative
## nesting depth.
## % By definition, this depth is nonzero.
## If the two depths are equal, we treat the computation as a matrix product,
## and specify result (R).
## Otherwise, we treat the less deeply nested argument as a scalar and the
## other as a matrix, and specify result (L) or (R), depending on ordering.
##
## For two {\GAP} objects $x$ and $y$ of which one is in
## `IsMultiplicativeGeneralizedRowVector' and the other is either not a list
## or is also in `IsMultiplicativeGeneralizedRowVector',
## $x / y$ is defined as $x * y^{-1}$.
##
gap> MultiplicationTest := function( left, right )
> local depth1, depth2, par, desired;
>
> if IsMultiplicativeGeneralizedRowVector( left ) and
> IsMultiplicativeGeneralizedRowVector( right ) then
> depth1:= NestingDepthMTest( left );
> depth2:= NestingDepthMTest( right );
> if IsOddInt( depth1 ) then
> if IsOddInt( depth2 ) or depth1 < depth2 then
> # <vec> * <vec> or <vec> * <mat>
> par:= ParallelOp( \*, left, right, "both" );
> if IsEmpty( par ) then
> error( "vector multiplication <left>*<right> with empty ",
> "support:\n", left, "\n", right, "\n" );
> else
> desired:= SumWithHoles( par );
> fi;
> else
> # <vec> * <scl>
> desired:= ListWithPrescribedHoles( left, x -> x * right );
> fi;
> elif IsOddInt( depth2 ) then
> if depth1 < depth2 then
> # <scl> * <vec>
> desired:= ListWithPrescribedHoles( right, x -> left * x );
> else
> # <mat> * <vec>
> desired:= ListWithPrescribedHoles( left, x -> x * right );
> fi;
> elif depth1 = depth2 then
> # <mat> * <mat>
> desired:= ListWithPrescribedHoles( left, x -> x * right );
> elif depth1 < depth2 then
> # <scl> * <mat>
> desired:= ListWithPrescribedHoles( right, x -> left * x );
> else
> # <mat> * <scl>
> desired:= ListWithPrescribedHoles( left, x -> x * right );
> fi;
> elif IsMultiplicativeGeneralizedRowVector( left ) and
> not IsList( right ) then
> desired:= ListWithPrescribedHoles( left, x -> x * right );
> elif IsMultiplicativeGeneralizedRowVector( right ) and
> not IsList( left ) then
> desired:= ListWithPrescribedHoles( right, x -> left * x );
> else
> return;
> fi;
> CompareTest( "Multiplication", [ left, right ], left * right, desired );
> if IsMultiplicativeGeneralizedRowVector( right )
> and IsOrdinaryMatrix( right )
> and Length( right ) = Length( right[1] )
> and NestingDepthM( right ) = 2
> and Inverse( right ) <> fail then
> CompareTest( "Division", [ left, right ], left / right,
> left * ( right^-1 ) );
> fi;
> end;;
#############################################################################
##
#F RunTest( <func>, <arg1>, ... )
##
## Call <func> for the remaining arguments, or for shallow copies of them
## or immutable copies.
##
gap> RunTest := function( arg )
> local combinations, i, entry;
>
> combinations:= [ ];
> for i in [ 2 .. Length( arg ) ] do
> entry:= [ arg[i] ];
> if IsCopyable( arg[i] ) then
> Add( entry, ShallowCopy( arg[i] ) );
> fi;
> if IsMutable( arg[i] ) then
> Add( entry, Immutable( arg[i] ) );
> fi;
> Add( combinations, entry );
> od;
> for entry in Cartesian( combinations ) do
> CallFuncList( arg[1], entry );
> od;
> end;;
#############################################################################
##
#F TestOfAdditiveListArithmetic( <R>, <dim> )
##
## For a ring or list of ring elements <R> (such that `Random( <R> )'
## returns an element in <R> and such that not all elements in <R> are
## zero),
## `TestOfAdditiveListArithmetic' performs the following tests of additive
## arithmetic operations.
## \beginlist
## \item{1.}
## If the elements of <R> are in `IsGeneralizedRowVector' then
## it is checked whether `Zero', `AdditiveInverse', and `\+'
## obey the definitions.
## \item{2.}
## If the elements of <R> are in `IsGeneralizedRowVector' then
## it is checked whether the sum of elements in <R> and (non-dense)
## plain lists of integers obeys the definitions.
## \item{3.}
## Check `Zero' and `AdditiveInverse' for nested plain lists of elements
## in <R>, and `\+' for elements in <R> and nested plain lists of
## elements in <R>.
## \endlist
##
gap> TestOfAdditiveListArithmetic := function( R, dim )
> local r, i, intlist, j, vec1, vec2, mat1, mat2, row;
>
> r:= Random( R );
> if IsGeneralizedRowVector( r ) then
>
> # tests of kind 1.
> for i in [ 1 .. 10 ] do
> RunTest( ZeroTest, Random( R ) );
> RunTest( AdditiveInverseTest, Random( R ) );
> RunTest( AdditionTest, Random( R ), Random( R ) );
> od;
>
> # tests of kind 2.
> for i in [ 1 .. 10 ] do
> RunTest( AdditionTest, Random( R ), [] );
> RunTest( AdditionTest, [], Random( R ) );
> r:= Random( R );
> intlist:= List( [ 1 .. Length( r ) + Random( [ -1 .. 1 ] ) ],
> x -> Random( Integers ) );
> for j in [ 1 .. Int( Length( r ) / 3 ) ] do
> Unbind( intlist[ Random( [ 1 .. Length( intlist ) ] ) ] );
> od;
> RunTest( AdditionTest, r, intlist );
> RunTest( AdditionTest, intlist, r );
> od;
>
> fi;
>
> # tests of kind 3.
> for i in [ 1 .. 10 ] do
>
> vec1:= List( [ 1 .. dim ], x -> Random( R ) );
> vec2:= List( [ 1 .. dim ], x -> Random( R ) );
>
> RunTest( ZeroTest, vec1 );
> RunTest( AdditiveInverseTest, vec1 );
> RunTest( AdditionTest, vec1, Random( R ) );
> RunTest( AdditionTest, Random( R ), vec2 );
> RunTest( AdditionTest, vec1, vec2 );
> RunTest( AdditionTest, vec1, [] );
> RunTest( AdditionTest, [], vec2 );
> Unbind( vec1[ dim ] );
> RunTest( AdditionTest, vec1, vec2 );
> Unbind( vec2[ Random( [ 1 .. dim ] ) ] );
> RunTest( ZeroTest, vec2 );
> RunTest( AdditiveInverseTest, vec1 );
> RunTest( AdditiveInverseTest, vec2 );
> RunTest( AdditionTest, vec1, vec2 );
> Unbind( vec1[ Random( [ 1 .. dim ] ) ] );
> RunTest( AdditionTest, vec1, vec2 );
>
> mat1:= RandomSquareArray( dim, R );
> mat2:= RandomSquareArray( dim, R );
>
> RunTest( ZeroTest, mat1 );
> RunTest( AdditiveInverseTest, mat1 );
> RunTest( TransposedMatTest, mat1 );
> RunTest( AdditionTest, mat1, Random( R ) );
> RunTest( AdditionTest, Random( R ), mat2 );
> RunTest( AdditionTest, vec1, mat2 );
> RunTest( AdditionTest, mat1, vec2 );
> RunTest( AdditionTest, mat1, mat2 );
> RunTest( AdditionTest, mat1, [] );
> RunTest( AdditionTest, [], mat2 );
> Unbind( mat1[ dim ] );
> row:= mat1[ Random( [ 1 .. dim-1 ] ) ];
> if not IsLockedRepresentationVector( row ) then
> Unbind( row[ Random( [ 1 .. dim ] ) ] );
> fi;
> RunTest( AdditionTest, mat1, mat2 );
> Unbind( mat2[ Random( [ 1 .. dim ] ) ] );
> RunTest( ZeroTest, mat2 );
> RunTest( AdditiveInverseTest, mat1 );
> RunTest( AdditiveInverseTest, mat2 );
> RunTest( TransposedMatTest, mat2 );
> RunTest( AdditionTest, mat1, mat2 );
> Unbind( mat1[ Random( [ 1 .. dim ] ) ] );
> RunTest( AdditionTest, mat1, mat2 );
>
> od;
> end;;
#############################################################################
##
#F TestOfMultiplicativeListArithmetic( <R>, <dim> )
##
## For a ring or list of ring elements <R> (such that `Random( <R> )'
## returns an element in <R> and such that not all elements in <R> are
## zero),
## `TestOfMultiplicativeListArithmetic' performs the following tests of
## multiplicative arithmetic operations.
## \beginlist
## \item{1.}
## If the elements of <R> are in `IsMultiplicativeGeneralizedRowVector'
## then it is checked whether `One', `Inverse', and `\*'
## obey the definitions.
## \item{2.}
## If the elements of <R> are in `IsMultiplicativeGeneralizedRowVector'
## then it is checked whether the product of elements in <R> and
## (non-dense) plain lists of integers obeys the definitions.
## (Note that contrary to the additive case, we need not chack the
## special case of a multiplication with an empty list.)
## \item{3.}
## Check `One' and `Inverse' for nested plain lists of elements
## in <R>, and `\*' for elements in <R> and nested plain lists of
## elements in <R>.
## \endlist
##
gap> TestOfMultiplicativeListArithmetic := function( R, dim )
> local r, i, intlist, j, vec1, vec2, mat1, mat2, row;
>
> r:= Random( R );
> if IsMultiplicativeGeneralizedRowVector( r ) then
>
> # tests of kind 1.
> for i in [ 1 .. 10 ] do
> RunTest( OneTest, Random( R ) );
> RunTest( InverseTest, Random( R ) );
> RunTest( MultiplicationTest, Random( R ), Random( R ) );
> od;
>
> # tests of kind 2.
> for i in [ 1 .. 10 ] do
> r:= Random( R );
> intlist:= List( [ 1 .. Length( r ) + Random( [ -1 .. 1 ] ) ],
> x -> Random( Integers ) );
> for j in [ 1 .. Int( Length( r ) / 3 ) ] do
> Unbind( intlist[ Random( [ 1 .. Length( intlist ) ] ) ] );
> od;
> RunTest( MultiplicationTest, r, intlist );
> RunTest( MultiplicationTest, intlist, r );
> od;
>
> fi;
>
> # tests of kind 3.
> for i in [ 1 .. 10 ] do
>
> vec1:= List( [ 1 .. dim ], x -> Random( R ) );
> vec2:= List( [ 1 .. dim ], x -> Random( R ) );
>
> RunTest( OneTest, vec1 );
> RunTest( InverseTest, vec1 );
> RunTest( MultiplicationTest, vec1, Random( R ) );
> RunTest( MultiplicationTest, Random( R ), vec2 );
> RunTest( MultiplicationTest, vec1, vec2 );
> Unbind( vec1[ dim ] );
> RunTest( MultiplicationTest, vec1, vec2 );
> Unbind( vec2[ Random( [ 1 .. dim ] ) ] );
> RunTest( OneTest, vec2 );
> RunTest( InverseTest, vec1 );
> RunTest( InverseTest, vec2 );
> RunTest( MultiplicationTest, vec1, vec2 );
> Unbind( vec1[ Random( [ 1 .. dim ] ) ] );
> RunTest( MultiplicationTest, vec1, vec2 );
>
> mat1:= RandomSquareArray( dim, R );
> mat2:= RandomSquareArray( dim, R );
>
> RunTest( OneTest, mat1 );
> RunTest( InverseTest, mat1 );
> RunTest( MultiplicationTest, mat1, Random( R ) );
> RunTest( MultiplicationTest, Random( R ), mat2 );
> RunTest( MultiplicationTest, vec1, mat2 );
> RunTest( MultiplicationTest, mat1, vec2 );
> RunTest( MultiplicationTest, mat1, mat2 );
> Unbind( mat1[ dim ] );
> row:= mat1[ Random( [ 1 .. dim-1 ] ) ];
> if not IsLockedRepresentationVector( row ) then
> Unbind( row[ Random( [ 1 .. dim ] ) ] );
> fi;
> RunTest( MultiplicationTest, vec1, mat2 );
> RunTest( MultiplicationTest, mat1, vec2 );
> RunTest( MultiplicationTest, mat1, mat2 );
> Unbind( mat2[ Random( [ 1 .. dim ] ) ] );
> RunTest( OneTest, mat2 );
> RunTest( InverseTest, mat1 );
> RunTest( InverseTest, mat2 );
> RunTest( MultiplicationTest, mat1, mat2 );
> Unbind( mat1[ Random( [ 1 .. dim ] ) ] );
> RunTest( MultiplicationTest, mat1, mat2 );
>
> od;
> end;;
#############################################################################
##
#F TestOfListArithmetic( <R>, <dimlist> )
##
gap> TestOfListArithmetic := function( R, dimlist )
> local n, len, bools, i;
>
> len:= 100;
> bools:= [ true, false ];
>
> for n in dimlist do
> TestOfAdditiveListArithmetic( R, n );
> TestOfMultiplicativeListArithmetic( R, n );
> R:= List( [ 1 .. len ], x -> Random( R ) );
> if IsMutable( R[1] ) and not ForAll( R, IsZero ) then
> for i in [ 1 .. len ] do
> if Random( bools ) then
> R[i]:= Immutable( R[i] );
> fi;
> od;
> TestOfAdditiveListArithmetic( R, n );
> TestOfMultiplicativeListArithmetic( R, n );
> fi;
> od;
> end;;
#############################################################################
##
## Here the tests start.
## (The dimension should always be at least 4,
## in order to avoid errors in inner products of non-dense lists.)
##
# over `GF(2)', `GF(3)', `GF(4)' (compressed elements)
gap> stddims:= [ 4, 5, 6, 8, 17, 32, 33 ];;
gap> TestOfListArithmetic( GF(2), stddims );
gap> TestOfListArithmetic( GF(3), stddims );
gap> TestOfListArithmetic( GF(4), stddims );
# over another small finite field (compressed elements)
gap> TestOfListArithmetic( GF(25), stddims );
# over a big finite (prime) field
gap> p:= NextPrimeInt( MAXSIZE_GF_INTERNAL );;
gap> TestOfListArithmetic( GF( p ), stddims );
# over the rationals
gap> TestOfListArithmetic( Rationals, [ 4 ] );
# over a residue class ring
gap> TestOfListArithmetic( Integers mod 12, [ 4 ] );
# over a ring of non-internal objects
gap> A:= QuaternionAlgebra( Rationals );;
gap> TestOfListArithmetic( A, [ 4 ] );
# over a matrix space/algebra over `GF(2)' (compressed elements)
gap> TestOfListArithmetic( GF(2)^[2,3], [ 4, 5, 6 ] );
# over a matrix space/algebra over another small finite field
# (compressed elements)
gap> TestOfListArithmetic( GF(5)^[2,3], [ 4, 5, 6 ] );
# over a matrix space/algebra over a big finite (prime) field
gap> p:= NextPrimeInt( MAXSIZE_GF_INTERNAL );;
gap> TestOfListArithmetic( GF( p )^[2,3], [ 4, 5, 6 ] );
# over a matrix space/algebra over the rationals
gap> TestOfListArithmetic( Rationals^[2,3], [ 4, 5, 6 ] );
# over a class function space (the elements are not mult. grvs)
gap> TestOfAdditiveListArithmetic( Irr( SymmetricGroup( 4 ) ), 4 );
# over a space of Lie matrices (the elements are not mult. grvs)
gap> TestOfAdditiveListArithmetic( LieAlgebra( GF(3)^[2,2] ), 4 );
# # over a group of block matrices
# gap> hom:= IrreducibleRepresentations( SymmetricGroup( 4 ) )[3];;
# gap> ind:= InducedRepresentation( hom, SymmetricGroup( 5 ) );;
# gap> blockmats:= Elements( Image( ind ) );;
# gap> # Note that `Random' for the matrix group would construct a matrix
# gap> # via the homomorphism to a perm. group, and this would not be a
# gap> # block matrix!
# gap> TestOfAdditiveListArithmetic( blockmats, 4 );
# gap> TestOfMultiplicativeListArithmetic( blockmats, 4 );
gap> STOP_TEST( "arithlst.tst", 4016930000);
#############################################################################
##
#E