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)); }
public static int GetNumberOfLayersInPointedFlowerQP(int numPeriods) => UsefulQuivers.GetNumberOfLayersInPointedFlowerQuiver(numPeriods);