Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346############################################################################# ## #W basis.gd GAP library Thomas Breuer ## ## #Y Copyright (C) 1996, 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 declares the operations for bases of free left modules. ## ############################################################################# ## ## <#GAPDoc Label="[1]{basis}"> ## In &GAP;, a <E>basis</E> of a free left <M>F</M>-module <M>V</M> is a list of vectors ## <M>B = [ v_1, v_2, \ldots, v_n ]</M> in <M>V</M> such that <M>V</M> is generated as a ## left <M>F</M>-module by these vectors and such that <M>B</M> is linearly ## independent over <M>F</M>. ## The integer <M>n</M> is the dimension of <M>V</M> (see <Ref Func="Dimension"/>). ## In particular, as each basis is a list (see Chapter <Ref Chap="Lists"/>), ## it has a length (see <Ref Func="Length"/>), and the <M>i</M>-th vector of <M>B</M> can be ## accessed as <M>B[i]</M>. ## <Example><![CDATA[ ## gap> V:= Rationals^3; ## ( Rationals^3 ) ## gap> B:= Basis( V ); ## CanonicalBasis( ( Rationals^3 ) ) ## gap> Length( B ); ## 3 ## gap> B[1]; ## [ 1, 0, 0 ] ## ]]></Example> ## <P/> ## The operations described below make sense only for bases of <E>finite</E> ## dimensional vector spaces. ## (In practice this means that the vector spaces must be <E>low</E> dimensional, ## that is, the dimension should not exceed a few hundred.) ## <P/> ## Besides the basic operations for lists ## (see <Ref Sect="Basic Operations for Lists"/>), ## the <E>basic operations for bases</E> are <Ref Func="BasisVectors"/>, ## <Ref Func="Coefficients"/>, ## <Ref Func="LinearCombination"/>, ## and <Ref Func="UnderlyingLeftModule"/>. ## These and other operations for arbitrary bases are described ## in <Ref Sect="Operations for Vector Space Bases"/>. ## <P/> ## For special kinds of bases, further operations are defined ## (see <Ref Sect="Operations for Special Kinds of Bases"/>). ## <P/> ## &GAP; supports the following three kinds of bases. ## <P/> ## <E>Relative bases</E> delegate the work to other bases of the same ## free left module, via basechange matrices (see <Ref Func="RelativeBasis"/>). ## <P/> ## <E>Bases handled by nice bases</E> delegate the work to bases ## of isomorphic left modules over the same left acting domain ## (see <Ref Sect="Vector Spaces Handled By Nice Bases"/>). ## <P/> ## Finally, of course there must be bases in &GAP; that really do the work. ## <P/> ## For example, in the case of a Gaussian row or matrix space <A>V</A> ## (see <Ref Sect="Row and Matrix Spaces"/>), ## <C>Basis( <A>V</A> )</C> is a semi-echelonized basis (see <Ref Func="IsSemiEchelonized"/>) ## that uses Gaussian elimination; such a basis is of the third kind. ## <C>Basis( <A>V</A>, <A>vectors</A> )</C> is either semi-echelonized or a relative basis. ## Other examples of bases of the third kind are canonical bases of finite ## fields and of abelian number fields. ## <P/> ## Bases handled by nice bases are described ## in <Ref Sect="Vector Spaces Handled By Nice Bases"/>. ## Examples are non-Gaussian row and matrix spaces, and subspaces of finite ## fields and abelian number fields that are themselves not fields. ## <#/GAPDoc> ## ############################################################################# ## #C IsBasis( <obj> ) ## ## <#GAPDoc Label="IsBasis"> ## <ManSection> ## <Filt Name="IsBasis" Arg='obj' Type='Category'/> ## ## <Description> ## In &GAP;, a <E>basis</E> of a free left module is an object that knows ## how to compute coefficients w.r.t. its basis vectors ## (see <Ref Func="Coefficients"/>). ## Bases are constructed by <Ref Func="Basis"/>. ## Each basis is an immutable list, ## the <M>i</M>-th entry being the <M>i</M>-th basis vector. ## <P/> ## (See <Ref Sect="Mutable Bases"/> for mutable bases.) ## <P/> ## <Example><![CDATA[ ## gap> V:= GF(2)^2;; ## gap> B:= Basis( V );; ## gap> IsBasis( B ); ## true ## gap> IsBasis( [ [ 1, 0 ], [ 0, 1 ] ] ); ## false ## gap> IsBasis( Basis( Rationals^2, [ [ 1, 0 ], [ 0, 1 ] ] ) ); ## true ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareCategory( "IsBasis", IsHomogeneousList and IsDuplicateFreeList ); ############################################################################# ## #C IsFiniteBasisDefault( <obj> ) ## ## <ManSection> ## <Filt Name="IsFiniteBasisDefault" Arg='obj' Type='Category'/> ## ## <Description> ## Objects in this category are in <C>IsListDefault</C>, that is, addition and ## multiplication for them is defined as for internally represented lists, ## the result presumably being an internally represented list. ## </Description> ## </ManSection> ## DeclareSynonym( "IsFiniteBasisDefault", IsBasis and IsCopyable and IsListDefault ); ############################################################################# ## #P IsCanonicalBasis( <B> ) ## ## <#GAPDoc Label="IsCanonicalBasis"> ## <ManSection> ## <Prop Name="IsCanonicalBasis" Arg='B'/> ## ## <Description> ## If the underlying free left module <M>V</M> of the basis <A>B</A> ## supports a canonical basis (see <Ref Func="CanonicalBasis"/>) then ## <Ref Func="IsCanonicalBasis"/> returns <K>true</K> if <A>B</A> is equal ## to the canonical basis of <M>V</M>, ## and <K>false</K> otherwise. ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareProperty( "IsCanonicalBasis", IsBasis ); ############################################################################# ## #P IsCanonicalBasisFullRowModule( <B> ) ## ## <#GAPDoc Label="IsCanonicalBasisFullRowModule"> ## <ManSection> ## <Prop Name="IsCanonicalBasisFullRowModule" Arg='B'/> ## ## <Description> ## <Index Subkey="for row spaces">canonical basis</Index> ## <Ref Func="IsCanonicalBasisFullRowModule"/> returns <K>true</K> if ## <A>B</A> is the canonical basis (see <Ref Func="IsCanonicalBasis"/>) ## of a full row module (see <Ref Func="IsFullRowModule"/>), ## and <K>false</K> otherwise. ## <P/> ## The <E>canonical basis</E> of a Gaussian row space is defined as the ## unique semi-echelonized (see <Ref Func="IsSemiEchelonized"/>) basis ## with the additional property that for <M>j > i</M> the position of the ## pivot of row <M>j</M> is bigger than the position of the pivot of row ## <M>i</M>, and that each pivot column contains exactly one nonzero entry. ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareProperty( "IsCanonicalBasisFullRowModule", IsBasis ); InstallTrueMethod( IsCanonicalBasis, IsCanonicalBasisFullRowModule ); InstallTrueMethod( IsSmallList, IsList and IsCanonicalBasisFullRowModule ); ############################################################################# ## #P IsCanonicalBasisFullMatrixModule( <B> ) ## ## <#GAPDoc Label="IsCanonicalBasisFullMatrixModule"> ## <ManSection> ## <Prop Name="IsCanonicalBasisFullMatrixModule" Arg='B'/> ## ## <Description> ## <Index Subkey="for matrix spaces">canonical basis</Index> ## <Ref Func="IsCanonicalBasisFullMatrixModule"/> returns <K>true</K> if ## <A>B</A> is the canonical basis (see <Ref Func="IsCanonicalBasis"/>) ## of a full matrix module (see <Ref Func="IsFullMatrixModule"/>), ## and <K>false</K> otherwise. ## <P/> ## The <E>canonical basis</E> of a Gaussian matrix space is defined as the ## unique semi-echelonized (see <Ref Func="IsSemiEchelonized"/>) basis ## for which the list of concatenations of the basis vectors forms the ## canonical basis of the corresponding Gaussian row space. ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareProperty( "IsCanonicalBasisFullMatrixModule", IsBasis ); InstallTrueMethod( IsCanonicalBasis, IsCanonicalBasisFullMatrixModule ); InstallTrueMethod( IsSmallList, IsList and IsCanonicalBasisFullMatrixModule ); ############################################################################# ## #P IsIntegralBasis( <B> ) ## ## <#GAPDoc Label="IsIntegralBasis"> ## <ManSection> ## <Prop Name="IsIntegralBasis" Arg='B'/> ## ## <Description> ## Let <A>B</A> be an <M>S</M>-basis of a <E>field</E> <M>F</M>, say, for a subfield <M>S</M> of <M>F</M>, ## and let <M>R</M> and <M>M</M> be the rings of algebraic integers in <M>S</M> and <M>F</M>, ## respectively. ## <C>IsIntegralBasis</C> returns <K>true</K> if <A>B</A> is also an <M>R</M>-basis of <M>M</M>, ## and <K>false</K> otherwise. ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareProperty( "IsIntegralBasis", IsBasis ); ############################################################################# ## #P IsNormalBasis( <B> ) ## ## <#GAPDoc Label="IsNormalBasis"> ## <ManSection> ## <Prop Name="IsNormalBasis" Arg='B'/> ## ## <Description> ## Let <A>B</A> be an <M>S</M>-basis of a <E>field</E> <M>F</M>, say, ## for a subfield <M>S</M> of <M>F</M>. ## <C>IsNormalBasis</C> returns <K>true</K> if <A>B</A> is invariant under ## the Galois group ## (see <Ref Attr="GaloisGroup" Label="of field"/>) ## of the field extension <M>F / S</M>, and <K>false</K> otherwise. ## <Example><![CDATA[ ## gap> B:= CanonicalBasis( GaussianRationals ); ## CanonicalBasis( GaussianRationals ) ## gap> IsIntegralBasis( B ); IsNormalBasis( B ); ## true ## false ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareProperty( "IsNormalBasis", IsBasis ); ############################################################################# ## #P IsSemiEchelonized( <B> ) ## ## <#GAPDoc Label="IsSemiEchelonized"> ## <ManSection> ## <Prop Name="IsSemiEchelonized" Arg='B'/> ## ## <Description> ## Let <A>B</A> be a basis of a Gaussian row or matrix space <M>V</M>, say ## (see <Ref Func="IsGaussianSpace"/>) over the field <M>F</M>. ## <P/> ## If <M>V</M> is a row space then <A>B</A> is semi-echelonized if the matrix formed ## by its basis vectors has the property that the first nonzero element in ## each row is the identity of <M>F</M>, ## and all values exactly below these pivot elements are the zero of <M>F</M> ## (cf. <Ref Func="SemiEchelonMat"/>). ## <P/> ## If <M>V</M> is a matrix space then <A>B</A> is semi-echelonized if the matrix ## obtained by replacing each basis vector by the concatenation of its rows ## is semi-echelonized (see above, cf. <Ref Func="SemiEchelonMats"/>). ## <Example><![CDATA[ ## gap> V:= GF(2)^2;; ## gap> B1:= Basis( V, [ [ 0, 1 ], [ 1, 0 ] ] * Z(2) );; ## gap> IsSemiEchelonized( B1 ); ## true ## gap> B2:= Basis( V, [ [ 0, 1 ], [ 1, 1 ] ] * Z(2) );; ## gap> IsSemiEchelonized( B2 ); ## false ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareProperty( "IsSemiEchelonized", IsBasis ); ############################################################################# ## #A BasisVectors( <B> ) ## ## <#GAPDoc Label="BasisVectors"> ## <ManSection> ## <Attr Name="BasisVectors" Arg='B'/> ## ## <Description> ## For a vector space basis <A>B</A>, <C>BasisVectors</C> returns the list of basis ## vectors of <A>B</A>. ## The lists <A>B</A> and <C>BasisVectors( <A>B</A> )</C> are equal; the main purpose of ## <C>BasisVectors</C> is to provide access to a list of vectors that does <E>not</E> ## know about an underlying vector space. ## <Example><![CDATA[ ## gap> V:= VectorSpace( Rationals, [ [ 1, 2, 7 ], [ 1/2, 1/3, 5 ] ] );; ## gap> B:= Basis( V, [ [ 1, 2, 7 ], [ 0, 1, -9/4 ] ] );; ## gap> BasisVectors( B ); ## [ [ 1, 2, 7 ], [ 0, 1, -9/4 ] ] ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareAttribute( "BasisVectors", IsBasis ); ############################################################################# ## #A EnumeratorByBasis( <B> ) ## ## <#GAPDoc Label="EnumeratorByBasis"> ## <ManSection> ## <Attr Name="EnumeratorByBasis" Arg='B'/> ## ## <Description> ## For a basis <A>B</A> of the free left <M>F</M>-module <M>V</M> of dimension <M>n</M>, say, ## <C>EnumeratorByBasis</C> returns an enumerator that loops over the elements of ## <M>V</M> as linear combinations of the vectors of <A>B</A> with coefficients the ## row vectors in the full row space (see <Ref Func="FullRowSpace"/>) of dimension <M>n</M> ## over <M>F</M>, in the succession given by the default enumerator of this row ## space. ## <Example><![CDATA[ ## gap> V:= GF(2)^3;; ## gap> enum:= EnumeratorByBasis( CanonicalBasis( V ) );; ## gap> Print( enum{ [ 1 .. 4 ] }, "\n" ); ## [ [ 0*Z(2), 0*Z(2), 0*Z(2) ], [ 0*Z(2), 0*Z(2), Z(2)^0 ], ## [ 0*Z(2), Z(2)^0, 0*Z(2) ], [ 0*Z(2), Z(2)^0, Z(2)^0 ] ] ## gap> B:= Basis( V, [ [ 1, 1, 1 ], [ 1, 1, 0 ], [ 1, 0, 0 ] ] * Z(2) );; ## gap> enum:= EnumeratorByBasis( B );; ## gap> Print( enum{ [ 1 .. 4 ] }, "\n" ); ## [ [ 0*Z(2), 0*Z(2), 0*Z(2) ], [ Z(2)^0, 0*Z(2), 0*Z(2) ], ## [ Z(2)^0, Z(2)^0, 0*Z(2) ], [ 0*Z(2), Z(2)^0, 0*Z(2) ] ] ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareAttribute( "EnumeratorByBasis", IsBasis ); ############################################################################# ## #A StructureConstantsTable( <B> ) ## ## <#GAPDoc Label="StructureConstantsTable"> ## <ManSection> ## <Attr Name="StructureConstantsTable" Arg='B'/> ## ## <Description> ## Let <A>B</A> be a basis of a free left module <M>R</M>, say, ## that is also a ring. ## In this case <Ref Func="StructureConstantsTable"/> returns ## a structure constants table <M>T</M> in sparse representation, ## as used for structure constants algebras ## (see Section <Ref Sect="Algebras" BookName="tut"/> ## of the &GAP; User's Tutorial). ## <P/> ## If <A>B</A> has length <M>n</M> then <M>T</M> is a list of length ## <M>n+2</M>. ## The first <M>n</M> entries of <M>T</M> are lists of length <M>n</M>. ## <M>T[ n+1 ]</M> is one of <M>1</M>, <M>-1</M>, or <M>0</M>; ## in the case of <M>1</M> the table is known to be symmetric, ## in the case of <M>-1</M> it is known to be antisymmetric, ## and <M>0</M> occurs in all other cases. ## <M>T[ n+2 ]</M> is the zero element of the coefficient domain. ## <P/> ## The coefficients w.r.t. <A>B</A> of the product of the <M>i</M>-th ## and <M>j</M>-th basis vector of <A>B</A> are stored in <M>T[i][j]</M> ## as a list of length <M>2</M>; ## its first entry is the list of positions of nonzero coefficients, ## the second entry is the list of these coefficients themselves. ## <P/> ## The multiplication in an algebra <M>A</M> with vector space basis ## <A>B</A> with basis vectors <M>[ v_1, \ldots, v_n ]</M> ## is determined by the so-called structure matrices ## <M>M_k = [ m_{ijk} ]_{ij}</M>, <M>1 \leq k \leq n</M>. ## The <M>M_k</M> are defined by <M>v_i v_j = \sum_k m_{ijk} v_k</M>. ## Let <M>a = [ a_1, \ldots, a_n ]</M> and <M>b = [ b_1, \ldots, b_n ]</M>. ## Then ## <Display Mode="M"> ## \left( \sum_i a_i v_i \right) \left( \sum_j b_j v_j \right) ## = \sum_{{i,j}} a_i b_j \left( v_i v_j \right) ## = \sum_k \left( \sum_j \left( \sum_i a_i m_{ijk} \right) b_j \right) v_k ## = \sum_k \left( a M_k b^{tr} \right) v_k. ## </Display> ## <P/> ## <Example><![CDATA[ ## gap> A:= QuaternionAlgebra( Rationals );; ## gap> StructureConstantsTable( Basis( A ) ); ## [ [ [ [ 1 ], [ 1 ] ], [ [ 2 ], [ 1 ] ], [ [ 3 ], [ 1 ] ], ## [ [ 4 ], [ 1 ] ] ], ## [ [ [ 2 ], [ 1 ] ], [ [ 1 ], [ -1 ] ], [ [ 4 ], [ 1 ] ], ## [ [ 3 ], [ -1 ] ] ], ## [ [ [ 3 ], [ 1 ] ], [ [ 4 ], [ -1 ] ], [ [ 1 ], [ -1 ] ], ## [ [ 2 ], [ 1 ] ] ], ## [ [ [ 4 ], [ 1 ] ], [ [ 3 ], [ 1 ] ], [ [ 2 ], [ -1 ] ], ## [ [ 1 ], [ -1 ] ] ], 0, 0 ] ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareAttribute( "StructureConstantsTable", IsBasis ); ############################################################################# ## #A UnderlyingLeftModule( <B> ) ## ## <#GAPDoc Label="UnderlyingLeftModule"> ## <ManSection> ## <Attr Name="UnderlyingLeftModule" Arg='B'/> ## ## <Description> ## For a basis <A>B</A> of a free left module <M>V</M>, say, ## <Ref Attr="UnderlyingLeftModule"/> returns <M>V</M>. ## <P/> ## The reason why a basis stores a free left module is that otherwise one ## would have to store the basis vectors and the coefficient domain ## separately. ## Storing the module allows one for example to deal with bases whose basis ## vectors have not yet been computed yet (see <Ref Func="Basis"/>); ## furthermore, in some cases it is convenient to test membership of a ## vector in the module before computing coefficients w.r.t. a basis. ## <!-- this happens for example for finite fields and cyclotomic fields--> ## <Example><![CDATA[ ## gap> B:= Basis( GF(2)^6 );; UnderlyingLeftModule( B ); ## ( GF(2)^6 ) ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareAttribute( "UnderlyingLeftModule", IsBasis ); ############################################################################# ## #O Coefficients( <B>, <v> ) . . . coefficients of <v> w.r. to the basis <B> ## ## <#GAPDoc Label="Coefficients"> ## <ManSection> ## <Oper Name="Coefficients" Arg='B, v'/> ## ## <Description> ## Let <M>V</M> be the underlying left module of the basis <A>B</A>, and <A>v</A> a vector ## such that the family of <A>v</A> is the elements family of the family of <M>V</M>. ## Then <C>Coefficients( <A>B</A>, <A>v</A> )</C> is the list of coefficients of <A>v</A> w.r.t. ## <A>B</A> if <A>v</A> lies in <M>V</M>, and <K>fail</K> otherwise. ## <Example><![CDATA[ ## gap> V:= VectorSpace( Rationals, [ [ 1, 2, 7 ], [ 1/2, 1/3, 5 ] ] );; ## gap> B:= Basis( V, [ [ 1, 2, 7 ], [ 0, 1, -9/4 ] ] );; ## gap> Coefficients( B, [ 1/2, 1/3, 5 ] ); ## [ 1/2, -2/3 ] ## gap> Coefficients( B, [ 1, 0, 0 ] ); ## fail ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareOperation( "Coefficients", [ IsBasis, IsVector ] ); ############################################################################# ## #O LinearCombination( <B>, <coeff> ) . . . . linear combination w. r.t. <B> ## ## <#GAPDoc Label="LinearCombination"> ## <ManSection> ## <Oper Name="LinearCombination" Arg='B, coeff'/> ## ## <Description> ## If <A>B</A> is a basis object (see <Ref Func="IsBasis"/>) ## or a homogeneous list of length <M>n</M>, say, ## and <A>coeff</A> is a row vector of the same length, ## <Ref Oper="LinearCombination"/> returns the vector ## <M>\sum_{{i = 1}}^n <A>coeff</A>[i] * <A>B</A>[i]</M>. ## <P/> ## Perhaps the most important usage is the case where <A>B</A> forms a ## basis. ## <Example><![CDATA[ ## gap> V:= VectorSpace( Rationals, [ [ 1, 2, 7 ], [ 1/2, 1/3, 5 ] ] );; ## gap> B:= Basis( V, [ [ 1, 2, 7 ], [ 0, 1, -9/4 ] ] );; ## gap> LinearCombination( B, [ 1/2, -2/3 ] ); ## [ 1/2, 1/3, 5 ] ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareOperation( "LinearCombination", [ IsHomogeneousList, IsHomogeneousList ] ); ############################################################################# ## #O SiftedVector( <B>, <v> ) . . . . . . residuum of <v> w.r.t. the basis <B> ## ## <#GAPDoc Label="SiftedVector"> ## <ManSection> ## <Oper Name="SiftedVector" Arg='B, v'/> ## ## <Description> ## Let <A>B</A> be a semi-echelonized basis (see <Ref Func="IsSemiEchelonized"/>) of a ## Gaussian row or matrix space <M>V</M> (see <Ref Func="IsGaussianSpace"/>), ## and <A>v</A> a row vector or matrix, respectively, of the same dimension as ## the elements in <M>V</M>. ## <C>SiftedVector</C> returns the <E>residuum</E> of <A>v</A> with respect to <A>B</A>, which ## is obtained by successively cleaning the pivot positions in <A>v</A> by ## subtracting multiples of the basis vectors in <A>B</A>. ## So the result is the zero vector in <M>V</M> if and only if <A>v</A> lies in <M>V</M>. ## <P/> ## <A>B</A> may also be a mutable basis (see <Ref Sect="Mutable Bases"/>) of a Gaussian row ## or matrix space. ## <Example><![CDATA[ ## gap> V:= VectorSpace( Rationals, [ [ 1, 2, 7 ], [ 1/2, 1/3, 5 ] ] );; ## gap> B:= Basis( V );; ## gap> SiftedVector( B, [ 1, 2, 8 ] ); ## [ 0, 0, 1 ] ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareOperation( "SiftedVector", [ IsBasis, IsVector ] ); ############################################################################# ## #O IteratorByBasis( <B> ) ## ## <#GAPDoc Label="IteratorByBasis"> ## <ManSection> ## <Oper Name="IteratorByBasis" Arg='B'/> ## ## <Description> ## For a basis <A>B</A> of the free left <M>F</M>-module <M>V</M> of dimension <M>n</M>, say, ## <C>IteratorByBasis</C> returns an iterator that loops over the elements of <M>V</M> ## as linear combinations of the vectors of <A>B</A> with coefficients the row ## vectors in the full row space (see <Ref Func="FullRowSpace"/>) of dimension <M>n</M> over ## <M>F</M>, in the succession given by the default enumerator of this row space. ## <Example><![CDATA[ ## gap> V:= GF(2)^3;; ## gap> iter:= IteratorByBasis( CanonicalBasis( V ) );; ## gap> for i in [ 1 .. 4 ] do Print( NextIterator( iter ), "\n" ); od; ## [ 0*Z(2), 0*Z(2), 0*Z(2) ] ## [ 0*Z(2), 0*Z(2), Z(2)^0 ] ## [ 0*Z(2), Z(2)^0, 0*Z(2) ] ## [ 0*Z(2), Z(2)^0, Z(2)^0 ] ## gap> B:= Basis( V, [ [ 1, 1, 1 ], [ 1, 1, 0 ], [ 1, 0, 0 ] ] * Z(2) );; ## gap> iter:= IteratorByBasis( B );; ## gap> for i in [ 1 .. 4 ] do Print( NextIterator( iter ), "\n" ); od; ## [ 0*Z(2), 0*Z(2), 0*Z(2) ] ## [ Z(2)^0, 0*Z(2), 0*Z(2) ] ## [ Z(2)^0, Z(2)^0, 0*Z(2) ] ## [ 0*Z(2), Z(2)^0, 0*Z(2) ] ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareOperation( "IteratorByBasis", [ IsBasis ] ); ############################################################################# ## #A Basis( <V>[, <vectors>] ) #O BasisNC( <V>, <vectors> ) ## ## <#GAPDoc Label="Basis"> ## <ManSection> ## <Attr Name="Basis" Arg='V[, vectors]'/> ## <Oper Name="BasisNC" Arg='V, vectors'/> ## ## <Description> ## Called with a free left <M>F</M>-module <A>V</A> as the only argument, ## <Ref Attr="Basis"/> returns an <M>F</M>-basis of <A>V</A> ## whose vectors are not further specified. ## <P/> ## If additionally a list <A>vectors</A> of vectors in <A>V</A> is given ## that forms an <M>F</M>-basis of <A>V</A> ## then <Ref Attr="Basis"/> returns this basis; ## if <A>vectors</A> is not linearly independent over <M>F</M> ## or does not generate <A>V</A> as a free left <M>F</M>-module ## then <K>fail</K> is returned. ## <P/> ## <Ref Oper="BasisNC"/> does the same as the two argument version of ## <Ref Attr="Basis"/>, except that it does not check ## whether <A>vectors</A> form a basis. ## <P/> ## If no basis vectors are prescribed then <Ref Attr="Basis"/> need not ## compute basis vectors; in this case, the vectors are computed ## in the first call to <Ref Attr="BasisVectors"/>. ## <Example><![CDATA[ ## gap> V:= VectorSpace( Rationals, [ [ 1, 2, 7 ], [ 1/2, 1/3, 5 ] ] );; ## gap> B:= Basis( V ); ## SemiEchelonBasis( <vector space over Rationals, with ## 2 generators>, ... ) ## gap> BasisVectors( B ); ## [ [ 1, 2, 7 ], [ 0, 1, -9/4 ] ] ## gap> B:= Basis( V, [ [ 1, 2, 7 ], [ 3, 2, 30 ] ] ); ## Basis( <vector space over Rationals, with 2 generators>, ## [ [ 1, 2, 7 ], [ 3, 2, 30 ] ] ) ## gap> Basis( V, [ [ 1, 2, 3 ] ] ); ## fail ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareAttribute( "Basis", IsFreeLeftModule ); DeclareOperation( "Basis", [ IsFreeLeftModule, IsHomogeneousList ] ); DeclareOperation( "BasisNC", [ IsFreeLeftModule, IsHomogeneousList ] ); ############################################################################# ## #A SemiEchelonBasis( <V>[, <vectors>] ) #O SemiEchelonBasisNC( <V>, <vectors> ) ## ## <#GAPDoc Label="SemiEchelonBasis"> ## <ManSection> ## <Attr Name="SemiEchelonBasis" Arg='V[, vectors]'/> ## <Oper Name="SemiEchelonBasisNC" Arg='V, vectors'/> ## ## <Description> ## Let <A>V</A> be a Gaussian row or matrix vector space over the field ## <M>F</M> (see <Ref Func="IsGaussianSpace"/>, ## <Ref Func="IsRowSpace"/>, <Ref Func="IsMatrixSpace"/>). ## <P/> ## Called with <A>V</A> as the only argument, ## <Ref Attr="SemiEchelonBasis"/> returns a basis of <A>V</A> ## that has the property <Ref Func="IsSemiEchelonized"/>. ## <P/> ## If additionally a list <A>vectors</A> of vectors in <A>V</A> is given ## that forms a semi-echelonized basis of <A>V</A> ## then <Ref Attr="SemiEchelonBasis"/> returns this basis; ## if <A>vectors</A> do not form a basis of <A>V</A> ## then <K>fail</K> is returned. ## <P/> ## <Ref Oper="SemiEchelonBasisNC"/> does the same as the two argument ## version of <Ref Attr="SemiEchelonBasis"/>, ## except that it is not checked whether <A>vectors</A> form ## a semi-echelonized basis. ## <Example><![CDATA[ ## gap> V:= GF(2)^2;; ## gap> B:= SemiEchelonBasis( V ); ## SemiEchelonBasis( ( GF(2)^2 ), ... ) ## gap> Print( BasisVectors( B ), "\n" ); ## [ [ Z(2)^0, 0*Z(2) ], [ 0*Z(2), Z(2)^0 ] ] ## gap> B:= SemiEchelonBasis( V, [ [ 1, 1 ], [ 0, 1 ] ] * Z(2) ); ## SemiEchelonBasis( ( GF(2)^2 ), <an immutable 2x2 matrix over GF2> ) ## gap> Print( BasisVectors( B ), "\n" ); ## [ [ Z(2)^0, Z(2)^0 ], [ 0*Z(2), Z(2)^0 ] ] ## gap> Coefficients( B, [ 0, 1 ] * Z(2) ); ## [ 0*Z(2), Z(2)^0 ] ## gap> Coefficients( B, [ 1, 0 ] * Z(2) ); ## [ Z(2)^0, Z(2)^0 ] ## gap> SemiEchelonBasis( V, [ [ 0, 1 ], [ 1, 1 ] ] * Z(2) ); ## fail ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareAttribute( "SemiEchelonBasis", IsFreeLeftModule ); DeclareOperation( "SemiEchelonBasis", [ IsFreeLeftModule, IsHomogeneousList ] ); DeclareOperation( "SemiEchelonBasisNC", [ IsFreeLeftModule, IsHomogeneousList ] ); #T In fact they should be declared for `IsGaussianSpace', or at least for #T `IsVectorSpace', but the files containing these categories are read later .. #T (Change this!) ############################################################################# ## #O RelativeBasis( <B>, <vectors> ) #O RelativeBasisNC( <B>, <vectors> ) ## ## <#GAPDoc Label="RelativeBasis"> ## <ManSection> ## <Oper Name="RelativeBasis" Arg='B, vectors'/> ## <Oper Name="RelativeBasisNC" Arg='B, vectors'/> ## ## <Description> ## A relative basis is a basis of the free left module <A>V</A> that delegates ## the computation of coefficients etc. to another basis of <A>V</A> via ## a basechange matrix. ## <P/> ## Let <A>B</A> be a basis of the free left module <A>V</A>, ## and <A>vectors</A> a list of vectors in <A>V</A>. ## <P/> ## <Ref Oper="RelativeBasis"/> checks whether <A>vectors</A> form a basis of <A>V</A>, ## and in this case a basis is returned in which <A>vectors</A> are ## the basis vectors; otherwise <K>fail</K> is returned. ## <P/> ## <Ref Oper="RelativeBasisNC"/> does the same, except that it omits the check. ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareOperation( "RelativeBasis", [ IsBasis, IsHomogeneousList ] ); DeclareOperation( "RelativeBasisNC", [ IsBasis, IsHomogeneousList ] ); ############################################################################# ## <#GAPDoc Label="[2]{basis}"> ## There are kinds of free <M>R</M>-modules for which efficient computations ## are possible because the elements are <Q>nice</Q>, ## for example subspaces of full row modules or of full matrix modules. ## In other cases, a <Q>nice</Q> canonical basis is known that allows one ## to do the necessary computations in the corresponding row module, ## for example algebras given by structure constants. ## <P/> ## In many other situations, one knows at least an isomorphism from the ## given module <M>V</M> to a <Q>nicer</Q> free left module <M>W</M>, ## in the sense that for each vector in <M>V</M>, ## the image in <M>W</M> can easily be computed, ## and analogously for each vector in <M>W</M>, ## one can compute the preimage in <M>V</M>. ## <P/> ## This allows one to delegate computations w.r.t. a basis <M>B</M>, ## say, of <M>V</M> to the corresponding basis <M>C</M>, say, of <M>W</M>. ## We call <M>W</M> the <E>nice free left module</E> of <M>V</M>, ## and <M>C</M> the <E>nice basis</E> of <M>B</M>. ## (Note that it may happen that also <M>C</M> delegates questions to a ## <Q>nicer</Q> basis.) ## The basis <M>B</M> indicates the intended behaviour by the filter ## <Ref Func="IsBasisByNiceBasis"/>, ## and stores <M>C</M> as value of the attribute <Ref Attr="NiceBasis"/>. ## <M>V</M> indicates the intended behaviour by the filter ## <Ref Filt="IsHandledByNiceBasis"/>, and stores <M>W</M> as value ## of the attribute <Ref Func="NiceFreeLeftModule"/>. ## <P/> ## The bijection between <M>V</M> and <M>W</M> is implemented by the ## functions <Ref Func="NiceVector"/> and <Ref Func="UglyVector"/>; ## additional data needed to compute images and preimages can be stored ## as value of <Ref Func="NiceFreeLeftModuleInfo"/>. ## <#/GAPDoc> ## ############################################################################# ## #F DeclareHandlingByNiceBasis( <name>, <info> ) #F InstallHandlingByNiceBasis( <name>, <record> ) ## ## <#GAPDoc Label="DeclareHandlingByNiceBasis"> ## <ManSection> ## <Func Name="DeclareHandlingByNiceBasis" Arg='name, info'/> ## <Func Name="InstallHandlingByNiceBasis" Arg='name, record'/> ## ## <Description> ## These functions are used to implement a new kind of free left modules ## that shall be handled via the mechanism of nice bases ## (see <Ref Sect="Vector Spaces Handled By Nice Bases"/>). ## <P/> ## <A>name</A> must be a string, ## a filter <M>f</M> with this name is created, and ## a logical implication from <M>f</M> to <Ref Filt="IsHandledByNiceBasis"/> ## is installed. ## <P/> ## <A>record</A> must be a record with the following components. ## <List> ## <Mark><C>detect</C> </Mark> ## <Item> ## a function of four arguments <M>R</M>, <M>l</M>, <M>V</M>, and <M>z</M>, ## where <M>V</M> is a free left module over the ring <M>R</M> with generators ## the list or collection <M>l</M>, and <M>z</M> is either the zero element of ## <M>V</M> or <K>false</K> (then <M>l</M> is nonempty); ## the function returns <K>true</K> if <M>V</M> shall lie in the filter <M>f</M>, ## and <K>false</K> otherwise; ## the return value may also be <K>fail</K>, which indicates that <M>V</M> is ## <E>not</E> to be handled via the mechanism of nice bases at all, ## </Item> ## <Mark><C>NiceFreeLeftModuleInfo</C> </Mark> ## <Item> ## the <C>NiceFreeLeftModuleInfo</C> method for left modules in <M>f</M>, ## </Item> ## <Mark><C>NiceVector</C> </Mark> ## <Item> ## the <C>NiceVector</C> method for left modules <M>V</M> in <M>f</M>; ## called with <M>V</M> and a vector <M>v \in V</M>, this function returns the ## nice vector <M>r</M> associated with <M>v</M>, and ## </Item> ## <Mark><C>UglyVector</C></Mark> ## <Item> ## the <Ref Func="UglyVector"/> method for left modules <M>V</M> in <M>f</M>; ## called with <M>V</M> and a vector <M>r</M> in the <C>NiceFreeLeftModule</C> value ## of <M>V</M>, this function returns the vector <M>v \in V</M> to which <M>r</M> is ## associated. ## </Item> ## </List> ## <P/> ## The idea is that all one has to do for implementing a new kind of free ## left modules handled by the mechanism of nice bases is to call ## <C>DeclareHandlingByNiceBasis</C> and <C>InstallHandlingByNiceBasis</C>, ## which causes the installation of the necessary methods and adds the pair ## <M>[ f, </M><C><A>record</A>.detect</C><M> ]</M> to the global list <C>NiceBasisFiltersInfo</C>. ## The <Ref Func="LeftModuleByGenerators"/> methods call ## <Ref Func="CheckForHandlingByNiceBasis"/>, which sets the appropriate filter ## for the desired left module if applicable. ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareGlobalFunction( "DeclareHandlingByNiceBasis" ); DeclareGlobalFunction( "InstallHandlingByNiceBasis" ); ############################################################################# ## #V NiceBasisFiltersInfo ## ## <#GAPDoc Label="NiceBasisFiltersInfo"> ## <ManSection> ## <Var Name="NiceBasisFiltersInfo"/> ## ## <Description> ## An overview of all kinds of vector spaces that are currently handled by ## nice bases is given by the global list <C>NiceBasisFiltersInfo</C>. ## Examples of such vector spaces are vector spaces of field elements ## (but not the fields themselves) and non-Gaussian row and matrix spaces ## (see <Ref Func="IsGaussianSpace"/>). ## </Description> ## </ManSection> ## <#/GAPDoc> ## BindGlobal( "NiceBasisFiltersInfo", [] ); ############################################################################# ## #F CheckForHandlingByNiceBasis( <R>, <gens>, <M>, <zero> ) ## ## <#GAPDoc Label="CheckForHandlingByNiceBasis"> ## <ManSection> ## <Func Name="CheckForHandlingByNiceBasis" Arg='R, gens, M, zero'/> ## ## <Description> ## Whenever a free left module is constructed for which the filter ## <C>IsHandledByNiceBasis</C> may be useful, ## <C>CheckForHandlingByNiceBasis</C> should be called. ## (This is done in the methods for <C>VectorSpaceByGenerators</C>, ## <C>AlgebraByGenerators</C>, <C>IdealByGenerators</C> etc. in the &GAP; library.) ## <P/> ## The arguments of this function are the coefficient ring <A>R</A>, the list ## <A>gens</A> of generators, the constructed module <A>M</A> itself, and the zero ## element <A>zero</A> of <A>M</A>; ## if <A>gens</A> is nonempty then the <A>zero</A> value may also be <K>false</K>. ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareGlobalFunction( "CheckForHandlingByNiceBasis" ); InstallGlobalFunction( "DeclareHandlingByNiceBasis", function( name, info ) local len, i; len:= Length( NiceBasisFiltersInfo ); for i in [ len, len-1 .. 1 ] do NiceBasisFiltersInfo[ i+1 ]:= NiceBasisFiltersInfo[i]; od; DeclareFilter( name ); NiceBasisFiltersInfo[1]:= [ ValueGlobal( name ), info ]; end ); ############################################################################# ## #F IsGenericFiniteSpace( <V> ) ## ## <ManSection> ## <Func Name="IsGenericFiniteSpace" Arg='V'/> ## ## <Description> ## If an <M>F</M>-vector space <A>V</A> is in the filter ## <Ref Filt="IsGenericFiniteSpace"/> then this expresses that <A>V</A> ## consists of elements in a <E>finite</E> vector space, ## and that <A>V</A> is handled via the mechanism of nice bases ## (see <Ref ???="..."/>) ## in the following way. ## (This is the generic treatment of finite vector spaces, better methods ## are installed for various special kinds of finite vector spaces.) ## Let <M>F</M> be of order <M>q</M>, <M>e_F</M> a list of the elements of ## <M>F</M>, ## <M>B = [ b_0, b_1, \ldots, b_k ]</M> be an <M>F</M>-basis of <M>V</M>, ## and let <M>e_V</M> be a list of elements of <M>V</M> with the property ## that ## <M>e_V[ 1 + \sum_{i=0}^k c_i q^i ] = \sum_{i=0}^k e_F[ c_i + 1 ] b_i</M> ## holds; ## then the <Ref Func="NiceVector"/> value of ## <M>e_V[ 1 + \sum_{i=0}^k c_i q^i ]</M> is the row vector ## <M>[ r_0, r_1, \ldots, r_k ]</M> with <M>r_i = e_F[ c_i + 1 ]</M>, ## and the <Ref Func="UglyVector"/> value of ## <M>[ r_0, r_1, \ldots, r_k ]</M> is <M>\sum_{i=0}^k r_i b_i</M>. ## <P/> ## The <Ref Func="NiceFreeLeftModuleInfo"/> value of <M>V</M> is a record ## with the following components. ## <List> ## <Mark><C>elements</C>:</Mark> ## <Item> ## a <E>strictly sorted</E> list <M>\tilde{e}_V</M> of elements of ## <M>V</M>, ## </Item> ## <Mark><C>numbers</C>:</Mark> ## <Item> ## a list <M>l</M> of the positive integers up to <M>q^{k+1}</M>, ## such that <M>e_V[ l[i] ] = \tilde{e}_V[i]</M> holds for ## <M>1 \leq i \leq q^{k+1}</M>. ## </Item> ## <Mark><C>q</C>:</Mark> ## <Item> ## the size of <M>F</M>, ## </Item> ## <Mark><C>fieldelements</C>:</Mark> ## <Item> ## the list <M>e_F</M>, ## </Item> ## <Mark><C>base</C>:</Mark> ## <Item> ## the list <M>B</M>. ## </Item> ## </List> ## <!-- use that the nice module is a full row space!--> ## <!-- (special method for NiceFreeLeftModule?)--> ## <!-- It is important that all other filters of this kind are installed <E>later</E>--> ## <!-- because otherwise the generic treatment may be chosen in cases for which--> ## <!-- a later filter indicates better methods.--> ## </Description> ## </ManSection> ## DeclareHandlingByNiceBasis( "IsGenericFiniteSpace", "for finite vector spaces (generic)" ); ############################################################################# ## #F IsSpaceOfRationalFunctions( <V> ) ## ## <ManSection> ## <Func Name="IsSpaceOfRationalFunctions" Arg='V'/> ## ## <Description> ## If an <M>F</M>-vector space <A>V</A> is in the filter <C>IsSpaceOfRationalFunctions</C> ## then this expresses that <A>V</A> consists of rational functions, ## and that <A>V</A> is handled via the mechanism of nice bases in the following ## way. ## Let <M>v_1, v_2, \ldots, v_k</M> be vector space generators of <A>V</A>, ## let <M>d</M> be a polynomial such that all <M>d \cdot v_i</M> are polynomials, ## and let <M>S</M> be the set of monomials that occur in these polynomials. ## Then the <C>NiceFreeLeftModuleInfo</C> value of <A>V</A> is a record with the ## following components. ## <List> ## <Mark><C>family</C> </Mark> ## <Item> ## the elements family of <A>V</A>, ## </Item> ## <Mark><C>monomials</C> </Mark> ## <Item> ## the list <M>S</M>, ## </Item> ## <Mark><C>denom</C> </Mark> ## <Item> ## the polynomial <M>d</M>, ## </Item> ## <Mark><C>zerocoeff</C> </Mark> ## <Item> ## the zero coefficient of elements in <A>V</A>, ## </Item> ## <Mark><C>zerovector</C> </Mark> ## <Item> ## the zero row vector in the nice free left module. ## </Item> ## </List> ## The <C>NiceVector</C> value of <M>v \in <A>V</A></M> is defined as the row vector of ## coefficients of <M>v</M> w.r.t. <M>S</M>. ## <P/> ## Finite dimensional free left modules of rational functions ## are by default handled via the mechanism of nice bases. ## </Description> ## </ManSection> ## DeclareHandlingByNiceBasis( "IsSpaceOfRationalFunctions", "for free left modules of rational functions" ); ############################################################################# ## #C IsBasisByNiceBasis( <B> ) ## ## <#GAPDoc Label="IsBasisByNiceBasis"> ## <ManSection> ## <Filt Name="IsBasisByNiceBasis" Arg='B' Type='Category'/> ## ## <Description> ## This filter indicates that the basis <A>B</A> delegates tasks such as the ## computation of coefficients (see <Ref Func="Coefficients"/>) to a basis of an ## isomorphic <Q>nicer</Q> free left module. ## <!-- Any object in <C>IsBasisByNiceBasis</C> must be a <E>small</E> list in the sense of--> ## <!-- <Ref Prop="IsSmallList"/>.--> ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareCategory( "IsBasisByNiceBasis", IsBasis and IsSmallList ); ############################################################################# ## #A NiceBasis( <B> ) ## ## <#GAPDoc Label="NiceBasis"> ## <ManSection> ## <Attr Name="NiceBasis" Arg='B'/> ## ## <Description> ## Let <A>B</A> be a basis of a free left module <A>V</A> that is handled via ## nice bases. ## If <A>B</A> has no basis vectors stored at the time of the first call to ## <C>NiceBasis</C> then <C>NiceBasis( <A>B</A> )</C> is obtained as ## <C>Basis( NiceFreeLeftModule( <A>V</A> ) )</C>. ## If basis vectors are stored then <C>NiceBasis( <A>B</A> )</C> is the result of the ## call of <C>Basis</C> with arguments <C>NiceFreeLeftModule( <A>V</A> )</C> ## and the <C>NiceVector</C> values of the basis vectors of <A>B</A>. ## <P/> ## Note that the result is <K>fail</K> if and only if the <Q>basis vectors</Q> ## stored in <A>B</A> are in fact not basis vectors. ## <P/> ## The attributes <C>GeneratorsOfLeftModule</C> of the underlying left modules ## of <A>B</A> and the result of <C>NiceBasis</C> correspond via <Ref Func="NiceVector"/> and ## <Ref Func="UglyVector"/>. ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareAttribute( "NiceBasis", IsBasisByNiceBasis ); ############################################################################# ## #O NiceBasisNC( <B> ) ## ## <ManSection> ## <Oper Name="NiceBasisNC" Arg='B'/> ## ## <Description> ## If the basis <A>B</A> has basis vectors bound then the attribute <C>NiceBasis</C> ## of <A>B</A> is set to <C>BasisNC( <A>W</A>, <A>nice</A> )</C> ## where <A>W</A> is the value of <C>NiceFreeLeftModule</C> for the underlying ## free left module of <A>B</A>. ## This means that it is <E>not</E> checked whether <A>B</A> really is a basis. ## </Description> ## </ManSection> ## DeclareOperation( "NiceBasisNC", [ IsBasisByNiceBasis ] ); ############################################################################# ## #A NiceFreeLeftModule( <V> ) . . . . nice free left module isomorphic to <V> ## ## <#GAPDoc Label="NiceFreeLeftModule"> ## <ManSection> ## <Attr Name="NiceFreeLeftModule" Arg='V'/> ## ## <Description> ## For a free left module <A>V</A> that is handled via the mechanism of nice ## bases, this attribute stores the associated free left module to which the ## tasks are delegated. ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareAttribute( "NiceFreeLeftModule", IsFreeLeftModule ); ############################################################################# ## #A NiceFreeLeftModuleInfo( <V> ) ## ## <#GAPDoc Label="NiceFreeLeftModuleInfo"> ## <ManSection> ## <Attr Name="NiceFreeLeftModuleInfo" Arg='V'/> ## ## <Description> ## For a free left module <A>V</A> that is handled via the mechanism of nice ## bases, this operation has to provide the necessary information (if any) ## for calls of <Ref Oper="NiceVector"/> and <Ref Oper="UglyVector"/>. ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareAttribute( "NiceFreeLeftModuleInfo", IsFreeLeftModule and IsHandledByNiceBasis ); ############################################################################# ## #O NiceVector( <V>, <v> ) #O UglyVector( <V>, <r> ) ## ## <#GAPDoc Label="NiceVector"> ## <ManSection> ## <Oper Name="NiceVector" Arg='V, v'/> ## <Oper Name="UglyVector" Arg='V, r'/> ## ## <Description> ## <Ref Oper="NiceVector"/> and <Ref Oper="UglyVector"/> provide the linear bijection between the ## free left module <A>V</A> and <C><A>W</A>:= NiceFreeLeftModule( <A>V</A> )</C>. ## <P/> ## If <A>v</A> lies in the elements family of the family of <A>V</A> then ## <C>NiceVector( <A>v</A> )</C> is either <K>fail</K> or an element in the elements family ## of the family of <A>W</A>. ## <P/> ## If <A>r</A> lies in the elements family of the family of <A>W</A> then ## <C>UglyVector( <A>r</A> )</C> is either <K>fail</K> or an element in the elements family ## of the family of <A>V</A>. ## <P/> ## If <A>v</A> lies in <A>V</A> (which usually <E>cannot</E> be checked without using <A>W</A>) ## then <C>UglyVector( <A>V</A>, NiceVector( <A>V</A>, <A>v</A> ) ) = <A>v</A></C>. ## If <A>r</A> lies in <A>W</A> (which usually <E>can</E> be checked) ## then <C>NiceVector( <A>V</A>, UglyVector( <A>V</A>, <A>r</A> ) ) = <A>r</A></C>. ## <P/> ## (This allows one to implement for example a membership test for <A>V</A> ## using the membership test in <A>W</A>.) ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareOperation( "NiceVector", [ IsFreeLeftModule and IsHandledByNiceBasis, IsObject ] ); DeclareOperation( "UglyVector", [ IsFreeLeftModule and IsHandledByNiceBasis, IsObject ] ); ############################################################################# ## #F BasisWithReplacedLeftModule( <B>, <V> ) ## ## <ManSection> ## <Func Name="BasisWithReplacedLeftModule" Arg='B, V'/> ## ## <Description> ## For a basis <A>B</A> and a left module <A>V</A> that is equal to the underlying ## left module of <A>B</A>, ## <C>BasisWithReplacedLeftModule</C> returns a basis equal to <A>B</A> except that ## the underlying left module of this basis is <A>V</A>. ## </Description> ## </ManSection> ## DeclareGlobalFunction( "BasisWithReplacedLeftModule" ); ############################################################################# ## #E