mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			652 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			652 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| #############################################################################
 | |
| ##
 | |
| #W  vspc.gi                     GAP library                     Thomas Breuer
 | |
| ##
 | |
| ##
 | |
| #Y  Copyright (C)  1997,  Lehrstuhl D für Mathematik,  RWTH Aachen,  Germany
 | |
| #Y  (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland
 | |
| #Y  Copyright (C) 2002 The GAP Group
 | |
| ##
 | |
| ##  This file contains generic methods for vector spaces.
 | |
| ##
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  SetLeftActingDomain( <extL>, <D> )
 | |
| ##
 | |
| ##  check whether the left acting domain <D> of the external left set <extL>
 | |
| ##  knows that it is a division ring.
 | |
| ##  This is used, e.g.,  to tell a free module over a division ring
 | |
| ##  that it is a vector space.
 | |
| ##
 | |
| InstallOtherMethod( SetLeftActingDomain,
 | |
|     "method to set also 'IsLeftActedOnByDivisionRing'",
 | |
|     [ IsAttributeStoringRep and IsLeftActedOnByRing, IsObject ],0,
 | |
|     function( extL, D )
 | |
|     if HasIsDivisionRing( D ) and IsDivisionRing( D ) then
 | |
|       SetIsLeftActedOnByDivisionRing( extL, true );
 | |
|     fi;
 | |
|     TryNextMethod();
 | |
|     end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  IsLeftActedOnByDivisionRing( <M> )
 | |
| ##
 | |
| InstallMethod( IsLeftActedOnByDivisionRing,
 | |
|     "method for external left set that is left acted on by a ring",
 | |
|     [ IsExtLSet and IsLeftActedOnByRing ],
 | |
|     function( M )
 | |
|     if IsIdenticalObj( M, LeftActingDomain( M ) ) then
 | |
|       TryNextMethod();
 | |
|     else
 | |
|       return IsDivisionRing( LeftActingDomain( M ) );
 | |
|     fi;
 | |
|     end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #F  VectorSpace( <F>, <gens>[, <zero>][, "basis"] )
 | |
| ##
 | |
| ##  The only difference between `VectorSpace' and `FreeLeftModule' shall be
 | |
| ##  that the left acting domain of a vector space must be a division ring.
 | |
| ##
 | |
| InstallGlobalFunction( VectorSpace, function( arg )
 | |
|     if Length( arg ) = 0 or not IsDivisionRing( arg[1] ) then
 | |
|       Error( "usage: VectorSpace( <F>, <gens>[, <zero>][, \"basis\"] )" );
 | |
|     fi;
 | |
|     return CallFuncList( FreeLeftModule, arg );
 | |
|     end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  AsSubspace( <V>, <C> )  . . . . . . . for a vector space and a collection
 | |
| ##
 | |
| InstallMethod( AsSubspace,
 | |
|     "for a vector space and a collection",
 | |
|     [ IsVectorSpace, IsCollection ],
 | |
|     function( V, C )
 | |
|     local newC;
 | |
| 
 | |
|     if not IsSubset( V, C ) then
 | |
|       return fail;
 | |
|     fi;
 | |
|     newC:= AsVectorSpace( LeftActingDomain( V ), C );
 | |
|     if newC = fail then
 | |
|       return fail;
 | |
|     fi;
 | |
|     SetParent( newC, V );
 | |
|     UseIsomorphismRelation( C, newC );
 | |
|     UseSubsetRelation( C, newC );
 | |
| 
 | |
|     return newC;
 | |
|     end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  AsLeftModule( <F>, <V> )  . . . . . .  for division ring and vector space
 | |
| ##
 | |
| ##  View the vector space <V> as a vector space over the division ring <F>.
 | |
| ##
 | |
| InstallMethod( AsLeftModule,
 | |
|     "method for a division ring and a vector space",
 | |
|     [ IsDivisionRing, IsVectorSpace ],
 | |
|     function( F, V )
 | |
| 
 | |
|     local W,        # the space, result
 | |
|           base,     # basis vectors of field extension
 | |
|           gen,      # loop over generators of 'V'
 | |
|           b,        # loop over 'base'
 | |
|           gens,     # generators of 'V'
 | |
|           newgens;  # extended list of generators
 | |
| 
 | |
|     if Characteristic( F ) <> Characteristic( LeftActingDomain( V ) ) then
 | |
| 
 | |
|       # This is impossible.
 | |
|       return fail;
 | |
| 
 | |
|     elif F = LeftActingDomain( V ) then
 | |
| 
 | |
|       # No change of the left acting domain is necessary.
 | |
|       return V;
 | |
| 
 | |
|     elif IsSubset( F, LeftActingDomain( V ) ) then
 | |
| 
 | |
|       # Check whether 'V' is really a space over the bigger field,
 | |
|       # that is, whether the set of elements does not change.
 | |
|       base:= BasisVectors( Basis( AsField( LeftActingDomain( V ), F ) ) );
 | |
|       for gen in GeneratorsOfLeftModule( V ) do
 | |
|         for b in base do
 | |
|           if not b * gen in V then
 | |
| 
 | |
|             # The field extension would change the set of elements.
 | |
|             return fail;
 | |
| 
 | |
|           fi;
 | |
|         od;
 | |
|       od;
 | |
| 
 | |
|       # Construct the space.
 | |
|       W:= LeftModuleByGenerators( F, GeneratorsOfLeftModule(V), Zero(V) );
 | |
| 
 | |
|     elif IsSubset( LeftActingDomain( V ), F ) then
 | |
| 
 | |
|       # View 'V' as a space over a smaller field.
 | |
|       # For that, the list of generators must be extended.
 | |
|       gens:= GeneratorsOfLeftModule( V );
 | |
|       if IsEmpty( gens ) then
 | |
|         W:= LeftModuleByGenerators( F, [], Zero( V ) );
 | |
|       else
 | |
| 
 | |
|         base:= BasisVectors( Basis( AsField( F, LeftActingDomain( V ) ) ) );
 | |
|         newgens:= [];
 | |
|         for b in base do
 | |
|           for gen in gens do
 | |
|             Add( newgens, b * gen );
 | |
|           od;
 | |
|         od;
 | |
|         W:= LeftModuleByGenerators( F, newgens );
 | |
| 
 | |
|       fi;
 | |
| 
 | |
|     else
 | |
| 
 | |
|       # View 'V' first as space over the intersection of fields,
 | |
|       # and then over the desired field.
 | |
|       return AsLeftModule( F,
 | |
|                  AsLeftModule( Intersection( F,
 | |
|                      LeftActingDomain( V ) ), V ) );
 | |
| 
 | |
|     fi;
 | |
| 
 | |
|     UseIsomorphismRelation( V, W );
 | |
|     UseSubsetRelation( V, W );
 | |
|     return W;
 | |
|     end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  ViewObj( <V> )  . . . . . . . . . . . . . . . . . . . view a vector space
 | |
| ##
 | |
| ##  print left acting domain, if known also dimension or no. of generators
 | |
| ##
 | |
| InstallMethod( ViewObj,
 | |
|     "for vector space with known generators",
 | |
|     [ IsVectorSpace and HasGeneratorsOfLeftModule ],
 | |
|     function( V )
 | |
|     Print( "<vector space over ", LeftActingDomain( V ), ", with ",
 | |
|            Length( GeneratorsOfLeftModule( V ) ), " generators>" );
 | |
|     end );
 | |
| 
 | |
| InstallMethod( ViewObj,
 | |
|     "for vector space with known dimension",
 | |
|     [ IsVectorSpace and HasDimension ],
 | |
|     1, # override method for known generators
 | |
|     function( V )
 | |
|     Print( "<vector space of dimension ", Dimension( V ),
 | |
|            " over ", LeftActingDomain( V ), ">" );
 | |
|     end );
 | |
| 
 | |
| InstallMethod( ViewObj,
 | |
|     "for vector space",
 | |
|     [ IsVectorSpace ],
 | |
|     function( V )
 | |
|     Print( "<vector space over ", LeftActingDomain( V ), ">" );
 | |
|     end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  PrintObj( <V> ) . . . . . . . . . . . . . . . . . . .  for a vector space
 | |
| ##
 | |
| InstallMethod( PrintObj,
 | |
|     "method for vector space with left module generators",
 | |
|     [ IsVectorSpace and HasGeneratorsOfLeftModule ],
 | |
|     function( V )
 | |
|     Print( "VectorSpace( ", LeftActingDomain( V ), ", ",
 | |
|            GeneratorsOfLeftModule( V ) );
 | |
|     if IsEmpty( GeneratorsOfLeftModule( V ) ) and HasZero( V ) then
 | |
|       Print( ", ", Zero( V ), " )" );
 | |
|     else
 | |
|       Print( " )" );
 | |
|     fi;
 | |
|     end );
 | |
| 
 | |
| InstallMethod( PrintObj,
 | |
|     "method for vector space",
 | |
|     [ IsVectorSpace ],
 | |
|     function( V )
 | |
|     Print( "VectorSpace( ", LeftActingDomain( V ), ", ... )" );
 | |
|     end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  \/( <V>, <W> )  . . . . . . . . .  factor of a vector space by a subspace
 | |
| #M  \/( <V>, <vectors> )  . . . . . .  factor of a vector space by a subspace
 | |
| ##
 | |
| InstallOtherMethod( \/,
 | |
|     "method for vector space and collection",
 | |
|     IsIdenticalObj,
 | |
|     [ IsVectorSpace, IsCollection ],
 | |
|     function( V, vectors )
 | |
|     if IsVectorSpace( vectors ) then
 | |
|       TryNextMethod();
 | |
|     else
 | |
|       return V / Subspace( V, vectors );
 | |
|     fi;
 | |
|     end );
 | |
| 
 | |
| InstallOtherMethod( \/,
 | |
|     "generic method for two vector spaces",
 | |
|     IsIdenticalObj,
 | |
|     [ IsVectorSpace, IsVectorSpace ],
 | |
|     function( V, W )
 | |
|     return ImagesSource( NaturalHomomorphismBySubspace( V, W ) );
 | |
|     end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  Intersection2Spaces( <AsStruct>, <Substruct>, <Struct> )
 | |
| ##
 | |
| InstallGlobalFunction( Intersection2Spaces,
 | |
|     function( AsStructure, Substructure, Structure )
 | |
|     return function( V, W )
 | |
|     local inters,  # intersection, result
 | |
|           F,       # coefficients field
 | |
|           gensV,   # list of generators of 'V'
 | |
|           gensW,   # list of generators of 'W'
 | |
|           VW,      # sum of 'V' and 'W'
 | |
|           B;       # basis of 'VW'
 | |
| 
 | |
|     if LeftActingDomain( V ) <> LeftActingDomain( W ) then
 | |
| 
 | |
|       # Compute the intersection as vector space over the intersection
 | |
|       # of the coefficients fields.
 | |
|       # (Note that the characteristic is the same.)
 | |
|       F:= Intersection2( LeftActingDomain( V ), LeftActingDomain( W ) );
 | |
|       return Intersection2( AsStructure( F, V ), AsStructure( F, W ) );
 | |
| 
 | |
|     elif IsFiniteDimensional( V ) and IsFiniteDimensional( W ) then
 | |
| 
 | |
|       # Compute the intersection of two spaces over the same field.
 | |
|       gensV:= GeneratorsOfLeftModule( V );
 | |
|       gensW:= GeneratorsOfLeftModule( W );
 | |
|       if   IsEmpty( gensV ) then
 | |
|         if Zero( V ) in W then
 | |
|           inters:= V;
 | |
|         else
 | |
|           inters:= [];
 | |
|         fi;
 | |
|       elif IsEmpty( gensW ) then
 | |
|         if Zero( V ) in W then
 | |
|           inters:= W;
 | |
|         else
 | |
|           inters:= [];
 | |
|         fi;
 | |
|       else
 | |
|         # Compute a common coefficient space.
 | |
|         VW:= LeftModuleByGenerators( LeftActingDomain( V ),
 | |
|                                      Concatenation( gensV, gensW ) );
 | |
|         B:= Basis( VW );
 | |
| 
 | |
|         # Construct the coefficient subspaces corresponding to 'V' and 'W'.
 | |
|         gensV:= List( gensV, x -> Coefficients( B, x ) );
 | |
|         gensW:= List( gensW, x -> Coefficients( B, x ) );
 | |
| 
 | |
|         # Construct the intersection of row spaces, and carry back to VW.
 | |
|         inters:= List( SumIntersectionMat( gensV, gensW )[2],
 | |
|                        x -> LinearCombination( B, x ) );
 | |
| 
 | |
|         # Construct the intersection space, if possible with a parent.
 | |
|         if     HasParent( V ) and HasParent( W )
 | |
|            and IsIdenticalObj( Parent( V ), Parent( W ) ) then
 | |
|           inters:= Substructure( Parent( V ), inters, "basis" );
 | |
|         elif IsEmpty( inters ) then
 | |
|           inters:= Substructure( V, inters, "basis" );
 | |
|           SetIsTrivial( inters, true );
 | |
|         else
 | |
|           inters:= Structure( LeftActingDomain( V ), inters, "basis" );
 | |
|         fi;
 | |
| 
 | |
|         # Run implications by the subset relation.
 | |
|         UseSubsetRelation( V, inters );
 | |
|         UseSubsetRelation( W, inters );
 | |
|       fi;
 | |
| 
 | |
|       # Return the result.
 | |
|       return inters;
 | |
| 
 | |
|     else
 | |
|       TryNextMethod();
 | |
|     fi;
 | |
|     end;
 | |
| end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  Intersection2( <V>, <W> ) . . . . . . . . . . . . . for two vector spaces
 | |
| ##
 | |
| InstallMethod( Intersection2,
 | |
|     "method for two vector spaces",
 | |
|     IsIdenticalObj,
 | |
|     [ IsVectorSpace, IsVectorSpace ],
 | |
|     Intersection2Spaces( AsLeftModule, SubspaceNC, VectorSpace ) );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  ClosureLeftModule( <V>, <a> ) . . . . . . . . . closure of a vector space
 | |
| ##
 | |
| InstallMethod( ClosureLeftModule,
 | |
|     "method for a vector space with basis, and a vector",
 | |
|     IsCollsElms,
 | |
|     [ IsVectorSpace and HasBasis, IsVector ],
 | |
|     function( V, w )
 | |
|     local   B; # basis of 'V'
 | |
| 
 | |
|     # We can test membership easily.
 | |
|     B:= Basis( V );
 | |
| #T why easily?
 | |
|     if Coefficients( B, w ) = fail then
 | |
| 
 | |
|       # In the case of a vector space, we know a basis of the closure.
 | |
|       B:= Concatenation( BasisVectors( B ), [ w ] );
 | |
|       V:= LeftModuleByGenerators( LeftActingDomain( V ), B );
 | |
|       UseBasis( V, B );
 | |
| 
 | |
|     fi;
 | |
|     return V;
 | |
|     end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| ##  Methods for collections of subspaces of a vector space
 | |
| ##
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #R  IsSubspacesVectorSpaceDefaultRep( <D> )
 | |
| ##
 | |
| ##  is the representation of domains of subspaces of a vector space <V>,
 | |
| ##  with the components 'structure' (with value <V>) and 'dimension'
 | |
| ##  (with value either the dimension of the subspaces in the domain
 | |
| ##  or the string '\"all\"', which means that the domain contains all
 | |
| ##  subspaces of <V>).
 | |
| ##
 | |
| DeclareRepresentation(
 | |
|     "IsSubspacesVectorSpaceDefaultRep",
 | |
|     IsComponentObjectRep,
 | |
|     [ "dimension", "structure" ] );
 | |
| #T not IsAttributeStoringRep?
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  PrintObj( <D> )  . . . . . . . . . . . . . . . . . for a subspaces domain
 | |
| ##
 | |
| InstallMethod( PrintObj,
 | |
|     "method for a subspaces domain",
 | |
|     [ IsSubspacesVectorSpace and IsSubspacesVectorSpaceDefaultRep ],
 | |
|     function( D )
 | |
|     if IsInt( D!.dimension ) then
 | |
|       Print( "Subspaces( ", D!.structure, ", ", D!.dimension, " )" );
 | |
|     else
 | |
|       Print( "Subspaces( ", D!.structure, " )" );
 | |
|     fi;
 | |
|     end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  Size( <D> ) . . . . . . . . . . . . . . . . . . .  for a subspaces domain
 | |
| ##
 | |
| ##  The number of $k$-dimensional subspaces in a $n$-dimensional space over
 | |
| ##  the field with $q$ elements is
 | |
| ##  $$
 | |
| ##  a(n,k) = \prod_{i=0}^{k-1} \frac{q^n-q^i}{q^k-q^i} =
 | |
| ##           \prod_{i=0}^{k-1} \frac{q^{n-i}-1}{q^{k-i}-1}.
 | |
| ##  $$
 | |
| ##  We have the recursion
 | |
| ##  $$
 | |
| ##  a(n,k+1) = a(n,k) \frac{q^{n-i}-1}{q^{i+1}-1}.
 | |
| ##  $$
 | |
| ##
 | |
| ##  (The number of all subspaces is $\sum_{k=0}^n a(n,k)$.)
 | |
| ##
 | |
| InstallMethod( Size,
 | |
|     "method for a subspaces domain",
 | |
|     [ IsSubspacesVectorSpace and IsSubspacesVectorSpaceDefaultRep ],
 | |
|     function( D )
 | |
| 
 | |
|     local k,
 | |
|           n,
 | |
|           q,
 | |
|           size,
 | |
|           qn,
 | |
|           qd,
 | |
|           ank,
 | |
|           i;
 | |
| 
 | |
|     if D!.dimension = "all" then
 | |
| 
 | |
|       # all subspaces of the space
 | |
|       n:= Dimension( D!.structure );
 | |
| 
 | |
|       q:= Size( LeftActingDomain( D!.structure ) );
 | |
|       size:= 1;
 | |
|       qn:= q^n;
 | |
|       qd:= q;
 | |
| 
 | |
|       # $a(n,0)$
 | |
|       ank:= 1;
 | |
| 
 | |
|       for k in [ 1 .. Int( (n-1)/2 ) ] do
 | |
| 
 | |
|         # Compute $a(n,k)$.
 | |
|         ank:= ank * ( qn - 1 ) / ( qd - 1 );
 | |
|         qn:= qn / q;
 | |
|         qd:= qd * q;
 | |
| 
 | |
|         size:= size + ank;
 | |
| 
 | |
|       od;
 | |
| 
 | |
|       size:= 2 * size;
 | |
| 
 | |
|       if n mod 2 = 0 then
 | |
| 
 | |
|         # Add the number of spaces of dimension $n/2$.
 | |
|         size:= size + ank * ( qn - 1 ) / ( qd - 1 );
 | |
|       fi;
 | |
| 
 | |
|     else
 | |
| 
 | |
|       # number of spaces of dimension 'k' only
 | |
|       n:= Dimension( D!.structure );
 | |
|       if   D!.dimension < 0 or
 | |
|            n < D!.dimension then
 | |
|         return 0;
 | |
|       elif n / 2 < D!.dimension then
 | |
|         k:= n - D!.dimension;
 | |
|       else
 | |
|         k:= D!.dimension;
 | |
|       fi;
 | |
| 
 | |
|       q:= Size( LeftActingDomain( D!.structure ) );
 | |
|       size:= 1;
 | |
| 
 | |
|       qn:= q^n;
 | |
|       qd:= q;
 | |
|       for i in [ 1 .. k ] do
 | |
|         size:= size * ( qn - 1 ) / ( qd - 1 );
 | |
|         qn:= qn / q;
 | |
|         qd:= qd * q;
 | |
|       od;
 | |
| 
 | |
|     fi;
 | |
| 
 | |
|     # Return the result.
 | |
|     return size;
 | |
|     end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  Enumerator( <D> ) . . . . . . . . . . . . . . . .  for a subspaces domain
 | |
| ##
 | |
| ##  Use the iterator to compute the elements list.
 | |
| #T This is not allowed!
 | |
| ##
 | |
| InstallMethod( Enumerator,
 | |
|     "method for a subspaces domain",
 | |
|     [ IsSubspacesVectorSpace and IsSubspacesVectorSpaceDefaultRep ],
 | |
|     function( D )
 | |
|     local iter,    # iterator for 'D'
 | |
|           elms;    # elements list, result
 | |
| 
 | |
|     iter:= Iterator( D );
 | |
|     elms:= [];
 | |
|     while not IsDoneIterator( iter ) do
 | |
|       Add( elms, NextIterator( iter ) );
 | |
|     od;
 | |
|     return elms;
 | |
|     end );
 | |
| #T necessary?
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  Iterator( <D> ) . . . . . . . . . . . . . . . . .  for a subspaces domain
 | |
| ##
 | |
| ##  uses the subspaces iterator for full row spaces and the mechanism of
 | |
| ##  associated row spaces.
 | |
| ##
 | |
| BindGlobal( "IsDoneIterator_Subspaces",
 | |
|     iter -> IsDoneIterator( iter!.associatedIterator ) );
 | |
| 
 | |
| BindGlobal( "NextIterator_Subspaces", function( iter )
 | |
|     local next;
 | |
|     next:= NextIterator( iter!.associatedIterator );
 | |
|     next:= List( GeneratorsOfLeftModule( next ),
 | |
|                  x -> LinearCombination( iter!.basis, x ) );
 | |
|     return Subspace( iter!.structure, next, "basis" );
 | |
|     end );
 | |
| 
 | |
| BindGlobal( "ShallowCopy_Subspaces",
 | |
|     iter -> rec( structure          := iter!.structure,
 | |
|                  basis              := iter!.basis,
 | |
|                  associatedIterator := ShallowCopy(
 | |
|                                            iter!.associatedIterator ) ) );
 | |
| 
 | |
| InstallMethod( Iterator,
 | |
|     "for a subspaces domain",
 | |
|     [ IsSubspacesVectorSpace and IsSubspacesVectorSpaceDefaultRep ],
 | |
|     function( D )
 | |
|     local V;      # the vector space
 | |
| 
 | |
|     V:= D!.structure;
 | |
|     return IteratorByFunctions( rec(
 | |
|                IsDoneIterator     := IsDoneIterator_Subspaces,
 | |
|                NextIterator       := NextIterator_Subspaces,
 | |
|                ShallowCopy        := ShallowCopy_Subspaces,
 | |
|                structure          := V,
 | |
|                basis              := Basis( V ),
 | |
|                associatedIterator := Iterator(
 | |
|                       Subspaces( FullRowSpace( LeftActingDomain( V ),
 | |
|                                                Dimension( V ) ),
 | |
|                                  D!.dimension ) ) ) );
 | |
|     end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  Subspaces( <V>, <dim> )
 | |
| ##
 | |
| InstallMethod( Subspaces,
 | |
|     "for a vector space, and an integer",
 | |
|     [ IsVectorSpace, IsInt ],
 | |
|     function( V, dim )
 | |
|     if IsFinite( V ) then
 | |
|       return Objectify( NewType( CollectionsFamily( FamilyObj( V ) ),
 | |
|                                      IsSubspacesVectorSpace
 | |
|                                  and IsSubspacesVectorSpaceDefaultRep ),
 | |
|                         rec(
 | |
|                              structure  := V,
 | |
|                              dimension  := dim
 | |
|                            )
 | |
|                       );
 | |
|     else
 | |
|       TryNextMethod();
 | |
|     fi;
 | |
|     end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  Subspaces( <V> )
 | |
| ##
 | |
| InstallMethod( Subspaces,
 | |
|     "for a vector space",
 | |
|     [ IsVectorSpace ],
 | |
|     function( V )
 | |
|     if IsFinite( V ) then
 | |
|       return Objectify( NewType( CollectionsFamily( FamilyObj( V ) ),
 | |
|                                      IsSubspacesVectorSpace
 | |
|                                  and IsSubspacesVectorSpaceDefaultRep ),
 | |
|                         rec(
 | |
|                              structure  := V,
 | |
|                              dimension  := "all"
 | |
|                            )
 | |
|                       );
 | |
|     else
 | |
|       TryNextMethod();
 | |
|     fi;
 | |
|     end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #F  IsSubspace( <V>, <U> ) . . . . . . . . . . . . . . . . . check <U> <= <V>
 | |
| ##
 | |
| InstallGlobalFunction( IsSubspace, function( V, U )
 | |
|     return IsVectorSpace( U ) and IsSubset( V, U );
 | |
| end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #M  IsVectorSpaceHomomorphism( <map> )
 | |
| ##
 | |
| InstallMethod( IsVectorSpaceHomomorphism,
 | |
|     [ IsGeneralMapping ],
 | |
|     function( map )
 | |
|     local S, R, F;
 | |
|     S:= Source( map );
 | |
|     if not IsVectorSpace( S ) then
 | |
|       return false;
 | |
|     fi;
 | |
|     R:= Range( map );
 | |
|     if not IsVectorSpace( R ) then
 | |
|       return false;
 | |
|     fi;
 | |
|     F:= LeftActingDomain( S );
 | |
|     return ( F = LeftActingDomain( R ) ) and IsLinearMapping( F, map );
 | |
|     end );
 | |
| 
 | |
| 
 | |
| #############################################################################
 | |
| ##
 | |
| #E
 | |
| 
 |