Environment to perform calculations of equivariant vector bundles on homogeneous varieties
Equivariant_Vector_Bundles_On_Homogeneous_Varieties__0-2 / src / Equivariant_Vector_Bundles_On_Homogeneous_Varieties / Extras / Young_Structure.sage.py
1842 viewsLicense: GPL3
ubuntu2204
12# This file was *autogenerated* from the file Young_Structure.sage3from sage.all_cmdline import * # import sage library45_sage_const_1 = Integer(1); _sage_const_0 = Integer(0); _sage_const_2 = Integer(2); _sage_const_3 = Integer(3)6from typing import Iterator78910class Young_Structure ( object ) :1112def __eq__ ( self , other ) -> bool :13if isinstance( other , self.__class__ ) : return self.Remove_Vanishing_Values().__repr__() == other.Remove_Vanishing_Values().__repr__()14else : return False151617def __getitem__ ( self , Coordinate :tuple[ int ] ) -> int :18"""Returns the value of a given coordinate."""19assert isinstance( Coordinate , tuple ) , 'The input for `Coordinate` need to be a tuple.'20assert len(Coordinate) == self.Rank() , 'The length of `Coordinate` need to coincide with the rank of `self`.'21for CoordinateCounter , CoordinateEntry in enumerate( Coordinate , start=_sage_const_1 ) :22assert isinstance( CoordinateEntry , ( int , Integer ) ) , 'The '+str(CoordinateCounter)+'-th entry of the coordinate need to be an integer.'23if Coordinate in self.Data().keys() : return self.Data()[Coordinate]24else : return _sage_const_0252627def __ge__ ( self , other ) -> bool :28"""Compares Young structures with respect to the >=-operator."""29return other <= self303132def __gt__ ( self , other ) -> bool :33"""Compares Young structures with respect to the >-operator."""34return other < self353637def __init__( self , Data :dict , Ranges :list ) -> None :38"""39Initialize a Young structure.4041INPUT:42- ``Data`` -- Dictionary ;43- ``Ranges`` -- List of 2-tuples ;4445OUTPUT: None.46"""47assert isinstance( Ranges , list ) , 'The input for `Ranges` need to be a list.'48for RangeCounter , Entry in enumerate( Ranges , start=_sage_const_1 ) :49assert isinstance( Entry , tuple ) , 'The '+str(RangeCounter)+'-th range need to be a tuple.'50assert len(Entry) == _sage_const_2 , 'The '+str(RangeCounter)+'-th range need to be of length 2.'51Minimum , Maximum = Entry52assert isinstance( Minimum , ( int , Integer ) ) , 'The minimum entry of the '+str(RangeCounter)+'-th range need to be an integer.'53assert isinstance( Maximum , ( int , Integer ) ) , 'The maximum entry of the '+str(RangeCounter)+'-th range need to be an integer.'54assert Minimum <= Maximum , 'For the '+str(RangeCounter)+'-th range, the minimum entry need to smaller or equal to the maximum entry.'55self._Ranges = Ranges5657self._Rank = len(Ranges)5859assert isinstance( Data , dict ) , 'The input for `Data` need to be dictionary.'60Adjusted_Data = dict({})61for ValueCounter , ( Coordinate , Value ) in enumerate( Data.items() , start=_sage_const_1 ) :62assert isinstance( Coordinate , tuple ) , 'The '+str(ValueCounter)+'-th coordinates need to be a tuple.'63assert len(Coordinate) <= self._Rank , 'The '+str(ValueCounter)+'-th coordinates need to be of length <= '+str(self._Rank)+'.'64Coordinate += tuple( ( self._Rank-len(Coordinate) )*[_sage_const_0 ] )65if Coordinate in Adjusted_Data.keys() : raise ValueError('CONFLICT! There are two values associated the same coordinate (after adjusting).')66else : Adjusted_Data.update({ Coordinate : Value })67for CoordinateCounter , CoordinateValue in enumerate( Coordinate ) :68assert isinstance( CoordinateValue , ( Integer , int ) ) , 'The '+str(CoordinateCounter+_sage_const_1 )+'-th entry of the '+str(ValueCounter)+'-th coordinate need to be an integer.'69Minimum = self._Ranges[CoordinateCounter][_sage_const_0 ]70assert Minimum <= CoordinateValue , 'The '+str(CoordinateCounter+_sage_const_1 )+'-th entry of the '+str(ValueCounter)+'-th coordinate need to >= '+str(Minimum)+'.'71Maximum = self._Ranges[CoordinateCounter][_sage_const_1 ]72assert CoordinateValue <= Maximum , 'The '+str(CoordinateCounter+_sage_const_1 )+'-th entry of the '+str(ValueCounter)+'-th coordinate need to <= '+str(Maximum)+'.'73self._Data = Adjusted_Data747576def __iter__ ( self ) -> Iterator[ tuple[ tuple[ int ] , int ] ] :77"""Returns an iterator of ``self``."""78return ( ( Coordinate , Value ) for Coordinate , Value in self.Data().items() )798081def __le__ ( self , other ) -> bool :82"""Compares Young structures with respect to the <=-operator."""83if self == other : return True84elif self < other : return True85else : return False868788# Synonym for the method `Rank`89def __len__( self ) :90"""Returns the rank ``self``."""91return self.Rank()929394def __ne__ ( self , other ) -> bool :95return not self == other969798def __repr__ ( self ) -> tuple[ dict[ tuple[int] : int ] , list[ tuple[ int , int ] ] ] :99"""Returns all attributes which are necessary to initialize the object."""100return self.Data() , self.Ranges()101102103def __str__ ( self ) -> str :104"""Returns a description in terms of diagrams (sliced if necessary)."""105if self.Rank() < _sage_const_3 :106# Low-dimensional Young structures can be printed.107( xMinimum , xMaximum ) , ( yMinimum , yMaximum ) = self.Ranges() + (_sage_const_2 -self.Rank())*[ ( _sage_const_0 , _sage_const_0 ) ]108Width = xMaximum-xMinimum+_sage_const_1109Height = yMaximum-yMinimum+_sage_const_1110M = matrix( nrows=Height , ncols=Width )111if _sage_const_0 in (ellipsis_range( yMinimum ,Ellipsis, yMaximum )) : ySubdivision = [ abs(yMinimum) ]112else : ySubdivision = None113if _sage_const_0 in (ellipsis_range( xMinimum ,Ellipsis, xMaximum )) : xSubdivision = [ abs(xMinimum) ]114else : xSubdivision = None115M.subdivide( ySubdivision , xSubdivision )116for Coordinate , Value in self :117xCoordinate , yCoordinate = Coordinate + tuple( (_sage_const_2 -self.Rank())*[ _sage_const_0 ] )118M[ yCoordinate-yMinimum , xCoordinate-xMinimum ] = Value119return str(M)120121else :122# Slice down to the first two coordinates x and y.123Output = ''124x = self.Coordinates()125Condition_Factors = []126for CoordinateCounter in range( self.Rank()-_sage_const_1 , _sage_const_1 , -_sage_const_1 ) :127Minimum , Maximum = self.Ranges()[CoordinateCounter]128Condition_Factors += [ [ x[CoordinateCounter] == Entry for Entry in (ellipsis_range( Minimum ,Ellipsis, Maximum )) ] ]129for Conditions in cartesian_product(Condition_Factors) :130YS = self.Locus( *Conditions )131for CoordinateCounter in range( YS.Rank()-_sage_const_1 , _sage_const_1 , -_sage_const_1 ) :132YS.Remove_Coordinate(CoordinateCounter)133Output += str( Conditions ) + '\n'134Output += str( YS ) + '\n'135Output += '\n'136137return Output138139140#ToDo: Test if `Permutation` is the correct instance.141def Conjugate ( self , Permutation: "Permutation" ) -> "Young_Structure" :142"""Returns a conjugated Young structure."""143assert len(Permutation) == self.Rank() , 'The length of the permutation need to coincide with the rank of `self`.'144New_Data = { tuple(Permutation.action(list(Coordinate))) : Value for Coordinate , Value in self }145New_Ranges = Permutation.action(self.Ranges())146return self.__class__( New_Data , New_Ranges )147148149@staticmethod150def Constructor ( *Input:tuple ) -> "Young_Structure" :151152def Get_Empty_Young_Structure ( Ranges :list[ tuple[ int , int ] ] ) -> "Young_Structure" :153Data = { tuple(Coordinate) : _sage_const_0 for Coordinate in cartesian_product([ (ellipsis_range( Minimum ,Ellipsis, Maximum ))154for Minimum , Maximum in Ranges155])156}157return Young_Structure( Data , Ranges )158159def Get_Young_Structure_From_Binary_Description ( String :str ) -> "Young_Structure" :160Keep_Running = True161while Keep_Running :162Keep_Running = False163for SubString in [ 'RL' , 'LR' , 'DU' , 'UD' ] :164if String.find(SubString) != -_sage_const_1 :165String = String.replace( SubString , '' )166Keep_Running = True167168xAmplitude = [_sage_const_0 ]+[ String[:Counter].count('R')-String[:Counter].count('L') for Counter in range(len(String)) ]169xRange = ( min(xAmplitude) , max(xAmplitude)-_sage_const_1 )170if xRange == (_sage_const_0 ,-_sage_const_1 ) : xRange = (_sage_const_0 ,_sage_const_0 )171xMinimum , xMaximum = xRange172yAmplitude = [_sage_const_0 ]+[ String[:Counter].count('D')-String[:Counter].count('U') for Counter in range(len(String)) ]173yRange = ( min(yAmplitude) , max(yAmplitude)-_sage_const_1 )174if yRange == (_sage_const_0 ,-_sage_const_1 ) : yRange = (_sage_const_0 ,_sage_const_0 )175yMinimum , yMaximum = yRange176177YS = Get_Empty_Young_Structure( [ xRange , yRange ] )178Data = YS.Data()179Ranges = YS.Ranges()180181xPointer , yPointer = (_sage_const_0 ,_sage_const_0 )182for Letter in String :183if Letter == 'R' :184for yPos in (ellipsis_range( yPointer ,Ellipsis, yMaximum )) :185Data[ (xPointer,yPos) ] += _sage_const_1186xPointer += _sage_const_1187elif Letter == 'L' :188xPointer -= _sage_const_1189for yPos in (ellipsis_range( yPointer ,Ellipsis, yMaximum )) :190Data[ (xPointer,yPos) ] -= _sage_const_1191elif Letter == 'D' :192yPointer += _sage_const_1193elif Letter == 'U' :194yPointer -= _sage_const_1195return Young_Structure( Data , Ranges )196197def Get_Young_Structure_From_Integer ( IntegerValue :int ) -> "Young_Structure" :198if IntegerValue == _sage_const_0 :199Data = dict({})200Ranges = [ ( _sage_const_0 , _sage_const_0 ) ]201else :202Minimum = min([ _sage_const_0 , IntegerValue ])203Maximum = max([ _sage_const_0 , IntegerValue ])204Data = { (Index,) : _sage_const_1 for Index in range(Minimum,Maximum) }205Ranges = [ ( Minimum , Maximum-_sage_const_1 ) ]206return Young_Structure( Data , Ranges )207208def Stacking_Young_Structures ( Stack :dict[ int : "Young_Structure" ] ) -> "Young_Structure" :209if _sage_const_0 < len( Stack.keys() ) :210New_Rank = max([_sage_const_0 ] + [ New_Slice.Rank() for New_Slice in Stack.values() ]) + _sage_const_1211New_Data = dict({})212New_Ranges = New_Rank * [ ( +infinity , -infinity ) ]213for New_Coordinate , New_Slice in Stack.items() :214Filling = tuple( (New_Rank-New_Slice.Rank()-_sage_const_1 )*[ _sage_const_0 ])215New_Data.update({ Coordinate + Filling + (New_Coordinate,) : Value for Coordinate , Value in New_Slice })216Adjusted_Ranges = [ ( min([ New_Ranges[RangeCounter][_sage_const_0 ] , Range[_sage_const_0 ] ]) , max([ New_Ranges[RangeCounter][_sage_const_1 ] , Range[_sage_const_1 ] ]) ) for RangeCounter , Range in enumerate( New_Slice.Ranges() ) ]217New_Ranges = Adjusted_Ranges218New_Ranges += [ ( min(Stack.keys()) , max(Stack.keys()) ) ]219else :220New_Data = dict({})221New_Ranges = []222return Young_Structure( New_Data , New_Ranges )223224if len(Input) == _sage_const_1 :225Input = Input[_sage_const_0 ]226if isinstance( Input , Integer ) :227return Get_Young_Structure_From_Integer( Input )228229elif isinstance( Input , ( list , tuple ) ) :230Stack = dict({})231for EntryCounter , Entry in enumerate( Input ) :232assert isinstance( Entry , ( int , Integer ) ) , 'If the input is given as list or tuple, then the '+str(EntryCounter+_sage_const_1 )+'-th entry need to be an integer.'233Stack.update({ EntryCounter : Get_Young_Structure_From_Integer(Entry) })234return Stacking_Young_Structures( Stack )235236elif isinstance( Input , str ) :237Input = Input.upper()238RightCounts = Input.count('R')239LeftCounts = Input.count('L')240DownCounts = Input.count('D')241UpCounts = Input.count('U')242assert len(Input) == sum([ RightCounts , LeftCounts , DownCounts , UpCounts ]) , 'The only admissible letters in `Input` are R (right), L (left), D (down), and U (up).'243assert RightCounts == LeftCounts , 'The number of R-letters ('+str(RightCounts)+'x) and L-letters ('+str(LeftCounts)+'x) need to coincide.'244assert DownCounts == UpCounts , 'The number of D-letters ('+str(DownCounts)+'x) and U-letters ('+str(UpCounts)+'x) need to coincide.'245return Get_Young_Structure_From_Binary_Description( Input )246247elif isinstance( Input , dict ) :248for New_Coordinate , New_Slice in Input.items() :249assert isinstance( New_Coordinate , ( int , Integer ) ) , 'If the input is a dictionary, then the keys need to be integers.'250assert isinstance( New_Slice , ( Young_Structure ) ) , 'If the input is a dictionary, then the values need to be Young structures.'251return Stacking_Young_Structures( Input )252253elif isinstance( Input , Young_Structure ) :254return Input255256else :257raise ValueError('The single input is inappropriate.')258259elif len(Input) == _sage_const_2 :260if Input[_sage_const_0 ] == 'Empty' :261Ranges = Input[_sage_const_1 ]262return Get_Empty_Young_Structure( Ranges )263264else :265raise ValueError('The two inputs are inappropriate.')266267else :268raise ValueError('The input is inappropriate.')269270271def Coordinates ( self ) -> "Variables" :272"""Returns the variable coordinates."""273return var([ 'x'+str(Counter) for Counter in range(self.Rank()) ])274275276def Data ( self ) -> dict[ tuple : int ] :277"""Returns the attribute ``_Data``."""278return self._Data279280281def Expand_Ranges ( self , New_Ranges ) -> "Young_Structure" :282"""Returns a Young structure with expanded ranges."""283assert isinstance( New_Ranges , list ) , 'The input for `New_Ranges` need to be a list.'284assert len(New_Ranges) == self.Rank() , 'The length of `New_Ranges` need to coincide with the rank of `self`.'285YS = self286for RangeCounter , New_Range in enumerate( New_Ranges ) :287if New_Range == None :288pass289290else :291Old_Minimum , Old_Maximum = YS.Ranges()[RangeCounter]292assert isinstance( New_Range , tuple ) , 'The '+str(RangeCounter)+'-th entry need to be a tuple.'293assert len(New_Range) == _sage_const_2 , 'The '+str(RangeCounter)+'-th range tuple need to be of length 2.'294New_Minimum , New_Maximum = New_Range295assert New_Minimum <= New_Maximum , 'The new minimum need to be smaller than or equal to the new maximum.'296assert New_Minimum <= Old_Minimum , 'The new minimum need to be smaller than or equal to the old minimum.'297assert Old_Maximum <= New_Maximum , 'The old maximum need to be smaller than or equal to the new maximum.'298YS._Ranges[RangeCounter] = New_Range299300return YS301302303def Locus ( self , *Conditions ) -> "Young_Structure" :304"""Returns locus of Young structure with respect to given conditions."""305for ConditionCounter , Condition in enumerate( Conditions , start=_sage_const_1 ) :306assert isinstance( Condition , sage.symbolic.expression.Expression ) , 'The input for the '+str(ConditionCounter)+'-th condition need to be an symbolic expression.'307x = self.Coordinates()308New_Data = dict({})309for Coordinate , Value in self :310Value_Satisfies_All_Conditions = True311for ConditionCounter , Condition in enumerate( Conditions , start=_sage_const_1 ) :312if bool( Condition({x[CoordinateCounter] : CoordinateEntry for CoordinateCounter , CoordinateEntry in enumerate( Coordinate ) }) ) :313pass314else :315Value_Satisfies_All_Conditions = False316break317if Value_Satisfies_All_Conditions : New_Data.update({ Coordinate : Value })318New_Ranges = self.Ranges()319return self.__class__( New_Data , New_Ranges )320321322def Move_Origin ( self , Steps:list[ int ] ) -> "Young_Structure" :323"""Returns a Young structure with moved origin."""324assert isinstance( Steps , list ) , 'The input for `Steps` need to be a list.'325assert len(Steps) == self.Rank() , 'The length of the tuple `Steps` need to coincide with the rank of `self`.'326for StepCounter , Step in enumerate( Steps ) :327assert isinstance( Step , ( int , Integer ) ) , 'The '+str(StepCounter)+'-th step need to be an integer.'328New_Data = { tuple( vector( ZZ , Coordinate ) + vector( ZZ , Steps ) ) : Value for Coordinate , Value in self }329New_Ranges = [ ( Minimum+Steps[RageCounter] , Maximum+Steps[RageCounter] ) for RageCounter , ( Minimum , Maximum ) in enumerate( self.Ranges() ) ]330return self.__class__( New_Data , New_Ranges )331332333def Ranges ( self ) -> list[ tuple[ int , int ] ] :334"""Returns the attribute ``_Ranges``."""335return self._Ranges336337338def Rank ( self ) -> int :339"""Returns the attribute ``_Rank``."""340return self._Rank341342343def Remove_Coordinate ( self , Index ) -> None :344"""Remove non-varying coordinates."""345assert Index in range(self.Rank()) , 'The input for `Index` need to be in the range '+str(range(self.Rank()))+'-.'346New_Data = dict({})347for Coordinate , Value in self :348Coordinate = tuple([ CoordinateEntry for CoordinateCounter , CoordinateEntry in enumerate(Coordinate) if CoordinateCounter != Index ])349New_Data.update({ Coordinate : Value })350New_Ranges = [ Range for RangeCounter , Range in enumerate( self.Ranges() ) if RangeCounter != Index ]351self.__init__( New_Data , New_Ranges )352353354def Remove_Vanishing_Values ( self ) -> "Young_Structure" :355"""Returns a Young structure without zero-values."""356return self.__class__( { Coordinate : Value for Coordinate , Value in self if Value != _sage_const_0 } , self.Ranges() )357358359def Sizes ( self ) -> list[ int ] :360"""Returns the sizes per direction."""361return [ Maximum-Minimum+_sage_const_1 for Minimum , Maximum in self.Ranges() ]362363364def Support ( self , Output_Type :str ='Absolute' ) -> "Young_Structure" :365"Returns the support."366if Output_Type in [ 'Absolute' , 'abs' ] :367Data = { tuple(self.Rank()*[_sage_const_0 ]) : _sage_const_0 }368Data.update({ Coordinate : _sage_const_1 for Coordinate , Value in self if Value != _sage_const_0 })369return self.__class__( Data , self.Ranges() )370elif Output_Type in [ 'Relative' , 'rel' , 'Sign' , 'sgn' ] :371return self.__class__( { Coordinate : sgn(Value) for Coordinate , Value in self } , self.Ranges() )372else :373raise ValueError('The input for `Output_Type` is inappropriate.')374375376def Volumne ( self ) -> int :377"""Returns the sum of all entries."""378return sum([ Value for Coordinate , Value in self ])379380381# ToDo: NEED TO BE DONE.382def __lt__ ( self , other ) -> bool :383"""Compares Young structures with respect to the <-operator."""384raise ValueError('The method `less-than` is not yet implemented.')385386387#def Compress ( self , Direction :int ) -> "Young_Structure" :388# assert isinstance( Direction , ( int , Integer ) ) , \389# 'The input for `Direction` need to be an integer.'390# assert Direction in range(self.Rank()) , \391# 'The value of `Direction` need to be in the range from 0 to '+str(self.Rank())+'.'392393#def Inflate ( self , Direction :int ) -> "Young_Structure" :394# pass395396397398class Young_Diagram ( Young_Structure ) :399400# Synonym for the method `Twist`401def __call__ ( self , Step :int =_sage_const_0 ) -> "Young_Diagram" :402"""Return a twisted Young diagram."""403return self.Twist( Step )404405406def __init__( self , Data :dict , Ranges :list or None =None ) -> None :407super( Young_Diagram , self ).__init__( Data , Ranges )408409assert self.Rank() == _sage_const_2 , '`self` need to be of rank 2.'410411xRange , yRange = self.Ranges()412xMinimum , xMaximum = xRange413yMinimum , yMaximum = yRange414assert xMinimum == _sage_const_0 , 'The x-minimum need to be zero.'415assert yMinimum == _sage_const_0 , 'The y-minimum need to be zero.'416417for Coordinate , Value in self :418xCoordinate , yCoordinate = Coordinate419assert Value in [ _sage_const_0 , _sage_const_1 ] , 'The value at coordinate '+str(Coordinate)+' need to be zero or one.'420if _sage_const_0 < xCoordinate :421assert Value <= self[(xCoordinate-_sage_const_1 ,yCoordinate)] , 'The value at '+str((xCoordinate-_sage_const_1 ,yCoordinate))+' need to be smaller than or equal to the value at '+str((xCoordinate,yCoordinate))+'.'422if _sage_const_0 < yCoordinate :423assert Value <= self[(xCoordinate,yCoordinate-_sage_const_1 )] , 'The value at '+str((xCoordinate,yCoordinate-_sage_const_1 ))+' need to be smaller than or equal to the value at '+str((xCoordinate,yCoordinate))+'.'424425426def __lshift__ ( self , Step :int =_sage_const_1 ) -> "Young_Diagram" :427"""Returns a shifted Young diagram (cyclic action)."""428return self >> -_sage_const_1 *Step429430431# Synonym for the method `Shift`432def __rshift__ ( self , Step :int =_sage_const_1 ) -> "Young_Diagram" :433"""Returns a shifted Young diagram (cyclic action)."""434return self.Shift( Step )435436437def Binary_Description ( self ) -> str :438Width = self.Width()439xPointer = Width440Height = self.Height()441yPointer = _sage_const_0442Description = ''443while _sage_const_0 < xPointer and yPointer < Height :444if self[xPointer,yPointer] < self[xPointer-_sage_const_1 ,yPointer] :445yPointer += _sage_const_1446Description += 'D'447else :448xPointer -= _sage_const_1449Description += 'L'450if _sage_const_0 < xPointer : Description += xPointer*'L'451if yPointer < Height : Description += (Height-yPointer)*'D'452return Description453454455def Complement ( self ) -> "Young_Diagram" :456"""Returns the complement of `self`."""457Width = self.Width()458Height = self.Height()459return self.__class__.Constructor( [ Width-Entry for Entry in self.Usual_Description()[::-_sage_const_1 ] ] , (Width,Height) )460461462def Column_Differences ( self ) -> list[int] :463"""Returns the differences s_{i}-s_{i+1} for i running through xRange"""464return self.Conjugate().Row_Differences()465466467def Column_Heights ( self ) -> list[ int ] :468"""Returns the height of each column."""469return self.Conjugate().Row_Widths()470471472def Column_Volumnes ( self ) -> list[ int ] :473"""Returns the volumne of each column."""474return self.Conjugate().Row_Volumnes()475476477def Columns ( self ) -> Iterator[ list[ int ] ] :478"""Returns an iterator running over the columns."""479return self.Conjugate().Rows()480481482def Conjugate ( self ) :483"""Returns the conjugated Young diagram."""484return super( Young_Diagram , self ).Conjugate( Permutation( '(1,2)' ) )485486487@staticmethod488def Constructor ( Description :tuple[ int ] or str , Sizes :tuple[ int , int ] or None =None ) -> "Young_Diagram" :489if Description in [ None , 'Empty' , [] , tuple([]) , dict({}) ] :490MinimumWidth = _sage_const_0491MinimumHeight = _sage_const_0492Description = [ _sage_const_0 ]493494elif isinstance( Description , ( list , tuple ) ) :495MinimumWidth = max([_sage_const_1 ] + list(Description))496MinimumHeight = len(Description)497Previous_Entry = +infinity498for EntryCounter , Current_Entry in enumerate( Description ) :499assert isinstance( Current_Entry , ( int , Integer ) ) , 'The '+str(EntryCounter)+'-th entry need to be an integer.'500assert Previous_Entry >= Current_Entry , 'The '+str(EntryCounter)+'-th entry need to be smaller than or equal to the previous one.'501Previous_Entry = Current_Entry502503elif isinstance( Description , str ) :504if set(Description).issubset({ 'D' , 'L' }) :505MinimumWidth = Description.count('L')506MinimumHeight = Description.count('D')507Description = MinimumWidth*'R' + Description + MinimumHeight*'U'508else :509raise ValueError( 'The input for `Description` is given as string, then its letters must be from the set { D (down) , L (letft) }.' )510511else :512raise ValueError( 'The input for `Description is inappropriate.`' )513514if Sizes == None : Sizes = ( MinimumWidth , MinimumHeight )515Width , Height = Sizes516assert MinimumWidth <= Width , 'The width need to be => '+str(MinimumWidth)+'.'517assert MinimumHeight <= Height , 'The height need to be => '+str(MinimumHeight)+'.'518519YS = Young_Structure.Constructor( Description )520YD = Young_Diagram( YS.Data() , YS.Ranges() )521return YD.Expand_Sizes( Width , Height )522523524def Cyclic_Orbit ( self ) -> Iterator[ "Young_Diagram" ] :525"""Runs through the cyclic orbit of `self`."""526First_Object = self527Current_Object = First_Object528while True :529yield Current_Object530Current_Object = Current_Object >> _sage_const_1531if Current_Object == First_Object : break532533534def Expand_Sizes ( self , New_Width :int , New_Height :int ) -> "Young_Diagram" :535"""Returns a Young diagram with expanded sizes."""536assert isinstance( New_Width , ( int , Integer ) ) , 'The input for `New_Width` need to be an integer.'537assert self.Width() <= New_Width , 'The new width need to be greater than or equal to the (old) width.'538assert isinstance( New_Height , ( int , Integer ) ) , 'The input for `New_Height` need to be an integer.'539assert self.Height() <= New_Height , 'The new height need to be greater than or equal to the (old) height.'540return self.Expand_Ranges( [ ( _sage_const_0 , New_Width-_sage_const_1 ) , ( _sage_const_0 , New_Height-_sage_const_1 ) ] )541542543def Height ( self ) -> int :544"""Returns the size in y-direction."""545return self.Sizes()[_sage_const_1 ]546547548def Is_Upper_Triangular ( self ) -> bool :549"""Tests if `self` is upper triangular"""550Width = self.Width()551Height = self.Height()552for xPos , Column_Height in enumerate( self.Column_Heights() ) :553if not Column_Height <= floor( Height*(Width-xPos-_sage_const_1 ) / Width ) : return False554return True555556557def N ( self ) -> int :558"""Returns the sum of width and height."""559return sum(self.Sizes())560561562def Row_Differences ( self ) -> list[int] :563"""Returns the differences s_{i}-s_{i+1} for j running through yRange"""564s = self.Row_Volumnes() + [ _sage_const_0 ]565return [ s[j]-s[j+_sage_const_1 ] for j in self.yRange() ]566567568def Row_Widths ( self ) -> list[ int ] :569"""Returns the volumne of each row."""570return [ sum(Row) for Row in self.Support().Rows() ]571572573def Row_Volumnes ( self ) -> list[ int ] :574"""Returns the volumne of each row."""575return [ sum(Row) for Row in self.Rows() ]576577578def Rows ( self ) -> Iterator[ list[ int ] ] :579"""Returns an iterator running over the rows."""580xRange = self.xRange()581yRange = self.yRange()582for yPos in yRange :583yield [ self[xPos,yPos] for xPos in xRange ]584585586def Shift ( self , Step :int =_sage_const_1 ) -> "Young_Diagram" :587"""Returns a shifted Young diagram (cyclic action)."""588assert isinstance( Step , ( int , Integer ) ) , 'The input for `Step` need to be an integer.'589Step = Step % self.N()590if Step == _sage_const_0 :591return self592else :593Old_Binary_Description = self.Binary_Description()594New_Binary_Description = Old_Binary_Description[-_sage_const_1 ] + Old_Binary_Description[ : -_sage_const_1 ]595New_Step = Step-_sage_const_1596return Young_Diagram.Constructor( New_Binary_Description ).Shift(New_Step)597598599def Twist ( self , Step :int =_sage_const_1 ) -> "Young_Diagram" :600"""Returns the Young diagram after a twist-action."""601assert isinstance( Step , ( int , Integer ) ) , 'The input for `Step` need to be an integer.'602New_YD = Young_Diagram.Constructor( [ Entry+Step for Entry in self.Usual_Description() ] )603New_Width = max([ New_YD.Width() , self.Width() ])604New_Height = max([ New_YD.Height() , self.Height() ])605return New_YD.Expand_Sizes( New_Width , New_Height )606607608# Synonym for the method `Row_Volumnes`.609def Usual_Description ( self ) -> list[ int ] :610"""Returns the usual description of `self`."""611return self.Row_Volumnes()612613614def Width ( self ) -> int :615"""Returns the size in x-direction."""616return self.Sizes()[_sage_const_0 ]617618619def xRange ( self ) -> list[ int ] :620"""Returns the range in x-direction."""621return (ellipsis_range( _sage_const_0 ,Ellipsis, self.Width()-_sage_const_1 ))622623624def yRange ( self ) -> list[ int ] :625"""Returns the range in y-direction."""626return (ellipsis_range( _sage_const_0 ,Ellipsis, self.Height()-_sage_const_1 ))627628629@staticmethod630def Lexicographically_Ordered ( Width :int , Height :int ) -> Iterator[ "Young_Diagrams" ] :631assert isinstance( Height , ( int , Integer ) ) , 'The input for `Height` need to be an integer.'632assert _sage_const_1 <= Height , 'The integer Height need to be greater than or equal to 1.'633assert isinstance( Width , ( int , Integer ) ) , 'The input for `Width` need to be an integer.'634assert _sage_const_1 <= Width , 'The integer Width need to be greater than or equal to 1.'635Usual_Descriptions = [ list(Usual_Description) for Usual_Description in IntegerListsLex( max_part=Width , length=Height , max_slope=_sage_const_0 ) ]636Usual_Descriptions.reverse()637for Usual_Description in Usual_Descriptions :638yield Young_Diagram.Constructor( Usual_Description , ( Width , Height ) )639640641@staticmethod642def Upper_Triangulars ( Width :int , Height :int ) -> Iterator[ "Young_Diagrams" ] :643assert isinstance( Height , ( int , Integer ) ) , 'The input for `Height` need to be an integer.'644assert _sage_const_1 <= Height , 'The integer Height need to be greater than or equal to 1.'645assert isinstance( Width , ( int , Integer ) ) , 'The input for `Width` need to be an integer.'646assert _sage_const_1 <= Width , 'The integer Width need to be greater than or equal to 1.'647Ceiling = [ floor( Width*(Height-Counter)/Height ) for Counter in (ellipsis_range( _sage_const_1 ,Ellipsis, Height )) ]648Usual_Descriptions = [ list(Usual_Description) for Usual_Description in IntegerListsLex( max_part=Width , length=Height , ceiling=Ceiling , max_slope=_sage_const_0 ) ]649Usual_Descriptions.reverse()650for Usual_Description in Usual_Descriptions :651yield Young_Diagram.Constructor( Usual_Description , ( Width , Height ) )652653654@staticmethod655def Minimal_Upper_Triangulars ( Width :int , Height :int ) -> Iterator[ "Young_Diagrams" ] :656Orbits = []657for YD in Young_Diagram.Upper_Triangulars( Width , Height ) :658YD_Did_Already_Appear = False659for Partial_Orbit in Orbits :660if YD in Partial_Orbit :661YD_Did_Already_Appear = True662break663if not YD_Did_Already_Appear :664Orbit_Length = _sage_const_0665Partial_Orbit = []666for Fellow in YD.Cyclic_Orbit() :667Orbit_Length += _sage_const_1668if Fellow.Is_Upper_Triangular() : Partial_Orbit += [ Fellow ]669Orbits += [ Partial_Orbit ]670yield YD , Orbit_Length671672673674