예제 #1
0
        public static QuiverWithPotential <int> GetPointedFlowerQP(int numPeriods, int firstVertex = DefaultFirstVertex)
        {
            if (!PointedFlowerParameterIsValid(numPeriods))
            {
                throw new ArgumentOutOfRangeException(nameof(numPeriods));
            }

            int numLayers = UsefulQuivers.GetNumberOfLayersInPointedFlowerQuiver(numPeriods);
            int numVerticesInFullInnerLayer = 2 * numPeriods;
            int numVerticesInOuterLayer     = 3 * numPeriods;

            var potential = new Potential <int>();

            if (numLayers == 2)
            {
                int centerVertex = GetLayerVertices(0).Single();
                var nextLayer    = GetLayerVertices(1);
                for (int periodIndex = 0; periodIndex < numPeriods; periodIndex++)
                {
                    int indexInNextLayer = 3 * periodIndex;

                    // Square
                    var positiveCycleVertices = new int[] { centerVertex, nextLayer[indexInNextLayer], nextLayer[indexInNextLayer + 1], nextLayer[indexInNextLayer + 2], centerVertex };

                    // Triangle
                    var negativeCycleVertices = new int[] { centerVertex, nextLayer[indexInNextLayer + 3], nextLayer[indexInNextLayer + 2], centerVertex };

                    potential = potential.AddCycle(new DetachedCycle <int>(positiveCycleVertices), +1);
                    potential = potential.AddCycle(new DetachedCycle <int>(negativeCycleVertices), -1);
                }

                return(new QuiverWithPotential <int>(potential));
            }

            // Polygons between first and second layer
            {
                int centerVertex = GetLayerVertices(0).Single();
                var nextLayer    = GetLayerVertices(1);
                for (int periodIndex = 0; periodIndex < numPeriods; periodIndex++)
                {
                    int indexInNextLayer = 2 * periodIndex;

                    // Triangles
                    var positiveCycleVertices = new int[] { centerVertex, nextLayer[indexInNextLayer], nextLayer[indexInNextLayer + 1], centerVertex };
                    var negativeCycleVertices = new int[] { centerVertex, nextLayer[indexInNextLayer + 2], nextLayer[indexInNextLayer + 1], centerVertex };

                    potential = potential.AddCycle(new DetachedCycle <int>(positiveCycleVertices), +1);
                    potential = potential.AddCycle(new DetachedCycle <int>(negativeCycleVertices), -1);
                }
            }

            // Cobweb layers
            for (int layerIndex = 1; layerIndex < numLayers - 2; layerIndex++) // 0-based layer index
            {
                var curLayer  = GetLayerVertices(layerIndex);
                var nextLayer = GetLayerVertices(layerIndex + 1);
                for (int indexInLayer = 0; indexInLayer < numVerticesInFullInnerLayer; indexInLayer++)
                {
                    int sign = (layerIndex + indexInLayer).Modulo(2) == 0 ? +1 : -1;

                    var squareVertices = sign == +1 ?
                                         new int[] { curLayer[indexInLayer + 1], curLayer[indexInLayer], nextLayer[indexInLayer], nextLayer[indexInLayer + 1], curLayer[indexInLayer + 1] } :
                    new int[] { curLayer[indexInLayer], curLayer[indexInLayer + 1], nextLayer[indexInLayer + 1], nextLayer[indexInLayer], curLayer[indexInLayer] };
                    potential = potential.AddCycle(new DetachedCycle <int>(squareVertices), sign);
                }
            }

            // Outermost layer of polygons
            {
                int layerIndex = numLayers - 2;
                var curLayer   = GetLayerVertices(layerIndex);
                var nextLayer  = GetLayerVertices(layerIndex + 1);
                for (int indexInPeriod = 0; indexInPeriod < numPeriods; indexInPeriod++)
                {
                    // Add pentagon
                    int indexInPenultimateLayer = 2 * indexInPeriod;
                    int indexInUltimateLayer    = 3 * indexInPeriod;
                    int pentagonSign            = layerIndex.Modulo(2) == 0 ? +1 : -1; // Remember that layerIndex is the index of the *penultimate* layer
                    var pentagonVertices        = pentagonSign == +1 ?
                                                  new int[] { curLayer[indexInPenultimateLayer + 1], curLayer[indexInPenultimateLayer], nextLayer[indexInUltimateLayer], nextLayer[indexInUltimateLayer + 1], nextLayer[indexInUltimateLayer + 2], curLayer[indexInPenultimateLayer + 1] } :
                    new int[] { curLayer[indexInPenultimateLayer], curLayer[indexInPenultimateLayer + 1], nextLayer[indexInUltimateLayer + 2], nextLayer[indexInUltimateLayer + 1], nextLayer[indexInUltimateLayer], curLayer[indexInPenultimateLayer] };
                    potential = potential.AddCycle(new DetachedCycle <int>(pentagonVertices), pentagonSign);

                    // Add square
                    int squareSign = -pentagonSign;
                    indexInPenultimateLayer += 1;
                    indexInUltimateLayer    += 2;
                    var squareVertices = squareSign == +1 ?
                                         new int[] { curLayer[indexInPenultimateLayer + 1], curLayer[indexInPenultimateLayer], nextLayer[indexInUltimateLayer], nextLayer[indexInUltimateLayer + 1], curLayer[indexInPenultimateLayer + 1] } :
                    new int[] { curLayer[indexInPenultimateLayer], curLayer[indexInPenultimateLayer + 1], nextLayer[indexInUltimateLayer + 1], nextLayer[indexInUltimateLayer], curLayer[indexInPenultimateLayer] };
                    potential = potential.AddCycle(new DetachedCycle <int>(squareVertices), squareSign);
                }
            }

            var qp = new QuiverWithPotential <int>(potential);

            return(qp);

            CircularList <int> GetLayerVertices(int layerIndex)
            => new CircularList <int>(GetVerticesInPointedFlowerQPLayer(numPeriods, layerIndex, firstVertex));
        }
예제 #2
0
 public static int GetNumberOfLayersInPointedFlowerQP(int numPeriods)
 => UsefulQuivers.GetNumberOfLayersInPointedFlowerQuiver(numPeriods);