public virtual ComplexNumber[] Simulate(QuantumCircuit circuit) { double sum = circuit.ProbabilitySum(); if (sum > MathHelper.Eps) { if (sum < 1 - MathHelper.Eps || sum > 1 + MathHelper.Eps) { circuit.Normalize(sum); } ComplexNumber[] amplitudes = new ComplexNumber[circuit.AmplitudeLength]; for (int i = 0; i < amplitudes.Length; i++) { amplitudes[i] = circuit.Amplitudes[i]; } return(amplitudes); } else { //Initialize the all 0 vector ComplexNumber[] amplitudes = new ComplexNumber[circuit.AmplitudeLength]; amplitudes[0].Real = 1; return(amplitudes); } }
public virtual void SilumateInPlace(QuantumCircuit circuit, ref ComplexNumber[] amplitudes) { int length = circuit.AmplitudeLength; if (amplitudes == null || amplitudes.Length != length) { //Post message amplitudes = new ComplexNumber[length]; } double sum = circuit.ProbabilitySum(); //if if (sum > MathHelper.Eps) { if (sum < 1 - MathHelper.Eps || sum > 1 + MathHelper.Eps) { circuit.Normalize(sum); } for (int i = 0; i < amplitudes.Length; i++) { amplitudes[i] = circuit.Amplitudes[i]; } } else { //Initialize the all 0 vector amplitudes[0].Real = 1; } }
IronPython.Runtime.PythonDictionary getTeleportDictionaryFromData(out string heightDimensions, double[,] imageData, double[,] imageData2, double mixture, double normalization = 0, bool useLog = false) { dynamic teleportationHelper = pythonFile.TeleportationHelper("TeleportationHelper"); bool normalizeManually = normalization > 0; teleportationHelper.SetHeights(imageData, imageData2, imageData.GetLength(0), imageData.GetLength(1)); teleportationHelper.ApplySwap(mixture, useLog, normalizeManually); dynamic circuit = teleportationHelper.GetCircuit(); int numberofQubits = circuit.num_qubits; heightDimensions = circuit.name; QuantumCircuit quantumCircuit = QuantumImageHelper.ParseCircuit(circuit.data, numberofQubits); MicroQiskitSimulator simulator = new MicroQiskitSimulator(); quantumCircuit.Normalize(); double[] doubleArray = new double[0]; string[] stringArray = new string[0]; double[] probs = simulator.GetProbabilities(quantumCircuit); QuantumImageHelper.GetProbabilityArrays(probs, numberofQubits, ref doubleArray, ref stringArray); IronPython.Runtime.PythonDictionary dictionary = pythonFile.CombinedHeightFromProbabilities(stringArray, doubleArray, doubleArray.Length, numberofQubits, heightDimensions, useLog, normalization); return(dictionary); }
public static void TextureToColorCircuit(Texture2D inputTexture, out QuantumCircuit redCircuit, out QuantumCircuit greenCircuit, out QuantumCircuit blueCircuit, bool useLog = false) { int width = inputTexture.width; int height = inputTexture.height; int dimX = Mathf.CeilToInt(Mathf.Log(width) / Mathf.Log(2)); int[] linesWidth = MakeLinesInt(dimX); int dimY = dimX; int[] linesHeight = linesWidth; if (width != height) { dimY = Mathf.CeilToInt(Mathf.Log(height) / Mathf.Log(2)); linesHeight = MakeLinesInt(dimY); } int maxHeight = MathHelper.IntegerPower(2, dimY); int numberOfQubits = dimX + dimY; redCircuit = new QuantumCircuit(numberOfQubits, numberOfQubits, true); greenCircuit = new QuantumCircuit(numberOfQubits, numberOfQubits, true); blueCircuit = new QuantumCircuit(numberOfQubits, numberOfQubits, true); Color color; int index; int posX; for (int x = 0; x < width; x++) { posX = linesWidth[x] * maxHeight; for (int y = 0; y < height; y++) { index = posX + linesHeight[y]; color = inputTexture.GetPixel(x, y); redCircuit.Amplitudes[index].Real = Math.Sqrt(color.r); greenCircuit.Amplitudes[index].Real = Math.Sqrt(color.g); blueCircuit.Amplitudes[index].Real = Math.Sqrt(color.b); } } redCircuit.Normalize(); greenCircuit.Normalize(); blueCircuit.Normalize(); }
public static QuantumCircuit HeightToCircuit(float[] height) { int numberOfQubits = Mathf.CeilToInt(Mathf.Log(height.Length) / Mathf.Log(2)); int[] lines = MakeLinesInt(numberOfQubits); QuantumCircuit circuit = new QuantumCircuit(numberOfQubits, numberOfQubits, true); int length = height.Length; for (int i = 0; i < length; i++) { circuit.Amplitudes[lines[i]].Real = Math.Sqrt(height[i]); } circuit.Normalize(); return(circuit); }
public static QuantumCircuit HeightToCircuit(float[,] heights2D) { int width = heights2D.GetLength(0); int height = heights2D.GetLength(1); int dimX = Mathf.CeilToInt(Mathf.Log(width) / Mathf.Log(2)); int[] linesWidth = MakeLinesInt(dimX); int dimY = dimX; int[] linesHeight = linesWidth; if (width != height) { dimY = Mathf.CeilToInt(Mathf.Log(height) / Mathf.Log(2)); linesHeight = MakeLinesInt(dimY); } int maxHeight = MathHelper.IntegerPower(2, dimY); int numberOfQubits = dimX + dimY; QuantumCircuit circuit = new QuantumCircuit(numberOfQubits, numberOfQubits, true); int index; int posX; for (int i = 0; i < width; i++) { posX = linesWidth[i] * maxHeight; for (int j = 0; j < height; j++) { index = posX + linesHeight[j]; circuit.Amplitudes[index].Real = heights2D[i, j]; } } circuit.Normalize(); return(circuit); }
IEnumerator meshAnimationOptimized() { //It is important to create a copy of the vertices and only use "inputMesh.vertices" only once // since this is a get function. Meaning in every call of the function the mesh will be copied. Vector3[] inputVertices = InputMesh.vertices; int numberOfVertices = inputVertices.Length; //We look at our input being 2 dimensional. One dimension is the number of vertices, //the other dimension is the vector x,y,z //We create lines for the first dimension the number of vertices int numberOfVertexCubits = Mathf.CeilToInt(Mathf.Log(numberOfVertices) / Mathf.Log(2)); //The lines are needed to encode the data in a way that encoding of neighbouring vertices only differ in 1 bit int[] linesVertices = QuantumImageHelper.MakeLinesInt(numberOfVertexCubits); //We create lines for the second dimension the vector x,y,z so there are only 3 values (thats where the 3 comes from). //The 2 is to transform the thing to base 2 since we need the logarithm in base 2. int numberOfVectorQubits = Mathf.CeilToInt(Mathf.Log(3) / Mathf.Log(2)); //The lines are needed to encode the data in a way that the encoding of x and y as well as y and z only differ in 1 bit. int[] linesVector = QuantumImageHelper.MakeLinesInt(numberOfVectorQubits); //Creating a circuit big enough to fit in the mesh data int numberOfQubits = numberOfVertexCubits + numberOfVectorQubits; QuantumCircuit circuit = new QuantumCircuit(numberOfQubits, numberOfQubits, true); //Since we work with probabilities, we need the values to be positive (or 0). //Therefore we want to translate the values adding an offset to our values, such that they become positive. //Getting the smallest (most negative) values to use for the displacement //initiate values as 0 float minX = 0; float minY = 0; float minZ = 0; for (int i = 0; i < inputVertices.Length; i++) { if (inputVertices[i].x < minX) { minX = inputVertices[i].x; } if (inputVertices[i].y < minY) { minY = inputVertices[i].y; } if (inputVertices[i].z < minZ) { minZ = inputVertices[i].z; } } //Needed to transform the position of our 2 dimensions mentioned above into a single array. //The indexes look like this: 0_X, 0_Y, 0_Z, 0_?, 1_X, 1_Y, 1_Z.... Where 0,1 etc stand for the vertex number //X,Y,Z stands for the respective coordinates and ? is just a placeholder which is not really needed (but we need to have a power of 2 so 4 values for our 3) int maxHeight = linesVector.Length; for (int i = 0; i < numberOfVertices; i++) { //We use the lines produced above to calculate the new position int index = linesVertices[i] * maxHeight; //We interpret the values as probabilities. And the amplitudes are the square root of the probabilities. circuit.Amplitudes[index + linesVector[0]].Real = Math.Sqrt(inputVertices[i].x - minX); circuit.Amplitudes[index + linesVector[1]].Real = Math.Sqrt(inputVertices[i].y - minY); circuit.Amplitudes[index + linesVector[2]].Real = Math.Sqrt(inputVertices[i].z - minZ); } //We need to normalize the circuit, since probabilities should add up to 1. //We store the factor used for normalization in order to reverse this scaling later. circuit.Normalize(); double normalizationFactor = circuit.OriginalSum; //We don't want to allocate as phew memory as possible in order to minimize garbage collection //Therefore, we reuse the defined arrays double[] realAmplitudes = new double[circuit.AmplitudeLength]; Vector3[] outPutVertices = new Vector3[numberOfVertices]; //Making a copy of the amplitudes of the circuit for (int i = 0; i < circuit.AmplitudeLength; i++) { realAmplitudes[i] = circuit.Amplitudes[i].Real; } //Creating a new mesh, at this point it is just a copy of the input mesh Mesh outputMesh = new Mesh(); outputMesh.name = InputMesh.name + " blurred"; outputMesh.vertices = inputVertices; outputMesh.triangles = InputMesh.triangles; outputMesh.uv = InputMesh.uv; outputMesh.RecalculateNormals(); outputMesh.RecalculateTangents(); MicroQiskitSimulator simulator = new MicroQiskitSimulator(); double[] probs = new double[circuit.AmplitudeLength]; //simulator.GetProbabilities(circuit); ComplexNumber[] amplitudes = new ComplexNumber[circuit.AmplitudeLength]; //Setting the new mesh to the target //We can now just manipulate the vertices of this mesh in order to change it. //No need to create new meshes TargetMesh.sharedMesh = outputMesh; OutputMesh = outputMesh; float rotation = 0.0f; float progress = 0; //Making sure to have no endless loop if (Duration <= 0) { Duration = 1; } //Creating an animation by blurring the mesh step by step //Duration is the duration of the animation, StartRotation and Endrotation give //The starting points and endpoints of the animation the rest is interpolated. while (progress < 1) { //Calculating progress for the animation progress += Time.deltaTime / Duration; //Rotation is interpolated between endRotation and startRtoation depending on progress rotation = progress * EndRotation + (1 - progress) * StartRotation; //Resetting the circuit (deleting the gates) circuit.ResetGates(); //Reusing the circuit by filling in the original values before the calculation again for (int i = 0; i < circuit.AmplitudeLength; i++) { circuit.Amplitudes[i].Real = realAmplitudes[i]; } //Applying the operation to the circuit (the blur effect) ApplyPartialQ(circuit, rotation); //Calculating probabilities simulator.CalculateProbabilities(circuit, ref probs, ref amplitudes); //Filling in the new calculated values into the vertices for (int i = 0; i < numberOfVertices; i++) { int index = linesVertices[i] * maxHeight; //Since we have probabilities already we do not need to square them. //We undo the normalization from above and the translation (offset) from the beginning outPutVertices[i].x = (float)(probs[index + linesVector[0]] * normalizationFactor) + minX; outPutVertices[i].y = (float)(probs[index + linesVector[1]] * normalizationFactor) + minY; outPutVertices[i].z = (float)(probs[index + linesVector[2]] * normalizationFactor) + minZ; } //We set the new vertices to the mesh, this way the mesh changes its form automatically //and we do not need to construct a new mesh. outputMesh.vertices = outPutVertices; //wait until next frame. yield return(null); } // Reverse animation going back to startRotation if (reverseAnimation) { while (progress > 0) { //Calculating progress for the animation going back progress -= Time.deltaTime / Duration; //Rotation is interpolated between endRotation and startRtoation depending on progress rotation = progress * EndRotation + (1 - progress) * StartRotation; //Resetting the circuit (deleting the gates) circuit.ResetGates(); //Reusing the circuit by filling in the original values before the calculation again for (int i = 0; i < circuit.AmplitudeLength; i++) { circuit.Amplitudes[i].Real = realAmplitudes[i]; } //Applying the operation to the circuit (the blur effect) ApplyPartialQ(circuit, rotation); //Calculating probabilities simulator.CalculateProbabilities(circuit, ref probs, ref amplitudes); //Filling the new calculated values into the vertices for (int i = 0; i < numberOfVertices; i++) { int index = linesVertices[i] * maxHeight; //Since we have probabilities already we do not need to square them. //We undo the normalization from above and the translation (offset) from the beginning outPutVertices[i].x = (float)(probs[index + linesVector[0]] * normalizationFactor) + minX; outPutVertices[i].y = (float)(probs[index + linesVector[1]] * normalizationFactor) + minY; outPutVertices[i].z = (float)(probs[index + linesVector[2]] * normalizationFactor) + minZ; } outputMesh.vertices = outPutVertices; //We set the new vertices to the mesh, this way the mesh changes its form automatically //and we do not need to construct a new mesh.outputMesh.vertices = outPutVertices; //wait until next frame. yield return(null); } } }
/// <summary> /// Creates a blurred version of the input mesh, according to the rotation. The bigger the rotation the stronger the blur effect. /// The model gets unrecognizeable as soon as the rotation gets to big /// </summary> /// <param name="inputMesh">The mesh to produce a blurred version of.</param> /// <param name="rotation">Can be between 0 and 3.1415 (pi). For starting 0.1 would be a good value.</param> /// <returns>A blurred (distorted) mesh of the original input mesh. </returns> public Mesh CreateBluredMesh(Mesh inputMesh, float rotation) { //It is important to create a copy of the vertices and only use "inputMesh.vertices" only once // since this is a get function. Meaning in every call of the function the mesh will be copied. Vector3[] vertices = inputMesh.vertices; int numberOfVertices = vertices.Length; //We look at our input being 2 dimensional. One dimension is the number of vertices, //the other dimension is the vector x,y,z //We create lines for the first dimension the number of vertices int numberOfVertexCubits = Mathf.CeilToInt(Mathf.Log(numberOfVertices) / Mathf.Log(2)); //The lines are needed to encode the data in a way that encoding of neighbouring vertices only differ in 1 bit int[] linesVertices = QuantumImageHelper.MakeLinesInt(numberOfVertexCubits); //We create lines for the second dimension the vector x,y,z so there are only 3 values (thats where the 3 comes from). //The 2 is to transform the thing to base 2 since we need the logarithm in base 2. int numberOfVectorQubits = Mathf.CeilToInt(Mathf.Log(3) / Mathf.Log(2)); //The lines are needed to encode the data in a way that the encoding of x and y as well as y and z only differ in 1 bit. int[] linesVector = QuantumImageHelper.MakeLinesInt(numberOfVectorQubits); //Creating a circuit big enough to fit in the mesh data int numberOfQubits = numberOfVertexCubits + numberOfVectorQubits; QuantumCircuit circuit = new QuantumCircuit(numberOfQubits, numberOfQubits, true); //Since we work with probabilities, we need the values to be positive (or 0). //Therefore we want to translate the values adding an offset to our values, such that they become positive. //Getting the smallest (most negative) values to use for the displacement //initiate values as 0 float minX = 0; float minY = 0; float minZ = 0; for (int i = 0; i < vertices.Length; i++) { if (vertices[i].x < minX) { minX = vertices[i].x; } if (vertices[i].y < minY) { minY = vertices[i].y; } if (vertices[i].z < minZ) { minZ = vertices[i].z; } } //Needed to transform the position of our 2 dimensions mentioned above into a single array. //The indexes look like this: 0_X, 0_Y, 0_Z, 0_?, 1_X, 1_Y, 1_Z.... Where 0,1 etc stand for the vertex number //X,Y,Z stands for the respective coordinates and ? is just a placeholder which is not really needed (but we need to have a power of 2 so 4 values for our 3) int maxHeight = linesVector.Length; for (int i = 0; i < numberOfVertices; i++) { //We use the lines produced above to calculate the new position int index = linesVertices[i] * maxHeight; //We interpret the values as probabilities. And the amplitudes are the square root of the probabilities. circuit.Amplitudes[index + linesVector[0]].Real = Math.Sqrt(vertices[i].x - minX); circuit.Amplitudes[index + linesVector[1]].Real = Math.Sqrt(vertices[i].y - minY); circuit.Amplitudes[index + linesVector[2]].Real = Math.Sqrt(vertices[i].z - minZ); } //We need to normalize the circuit, since probabilities should add up to 1. //We store the factor used for normalization in order to reverse this scaling later. circuit.Normalize(); double normalizationFactor = circuit.OriginalSum; //We apply the effect to the circuit. Here this is the normal blur effect also used in the images. ApplyPartialQ(circuit, rotation); //Calculating the probabilities after having applied the operation above SimulatorBase simulator = new MicroQiskitSimulator(); //MicroQiskitSimulator simulator = new MicroQiskitSimulator(); //QiskitSimulator simulator = new QiskitSimulator(); double[] probs = simulator.GetProbabilities(circuit); //Fill in the new calculated values back into the vertices for (int i = 0; i < numberOfVertices; i++) { int index = linesVertices[i] * maxHeight; //Since we have probabilities already we do not need to square them. //We undo the normalization from above and the translation (offset) from the beginning vertices[i].x = (float)(probs[index + linesVector[0]] * normalizationFactor) + minX; vertices[i].y = (float)(probs[index + linesVector[1]] * normalizationFactor) + minY; vertices[i].z = (float)(probs[index + linesVector[2]] * normalizationFactor) + minZ; } //creating the new mesh Mesh outputMesh = new Mesh(); //setting the newly calculated vertices outputMesh.vertices = vertices; //Copying most stuff from original mesh outputMesh.name = inputMesh.name + " blurred"; outputMesh.triangles = inputMesh.triangles; outputMesh.uv = inputMesh.uv; //Recalculating normals for correct lighning outputMesh.RecalculateNormals(); //returning the mesh return(outputMesh); }
public void Normalize() { Circuit.Normalize(); }