def nextMatrix(matrix, step, a, b, nRows):

        module = QuantumMath.vectorModule([a, b])

        if step[0] == step[1]:

            #diagonal
            matrix[step[0], step[0]] = 1

            matrix[nRows - 1, nRows - 1] *= -QuantumMath.conjugate(a)

            return matrix

        else:
            #! mejorar para no hacer la multiplicacion

            newMatrix = np.eye(nRows, dtype=complex)

            newMatrix[step[0], step[0]] = a / module

            newMatrix[step[1], step[1]] = -QuantumMath.conjugate(a) / module

            newMatrix[step[0], step[1]] = b / module

            newMatrix[step[1], step[0]] = QuantumMath.conjugate(b) / module

            #print (newMatrix)

            return np.dot(newMatrix, matrix)
    def generateRowReversePath(target1, target2, dic):

        nQubits = dic.getNQubits()

        if target1 == target2:

            #identity matrix
            basicId = AQP.generateBasic(standarGate=StandarGate.I,
                                        targets=[0],
                                        dic=dic)

            return [basicId]

        #convert targets to binary
        targetList1 = QuantumMath.toBinary(2**nQubits - target1 - 1, nQubits)
        targetList2 = QuantumMath.toBinary(2**nQubits - target2 - 1, nQubits)

        allsources = []
        for i in range(nQubits):
            allsources.append(i)

        idList = []

        for i in range(nQubits):

            if targetList1[i] == targetList2[i]:
                continue

            # create X gate to set all to 1
            targets = []
            sources = []
            for j in range(nQubits):
                if i == j:
                    continue
                if targetList1[j] == 1:
                    targets.append(j)
                sources.append(j)

            setTrueId = AQP.generateBasic(standarGate=StandarGate.X,
                                          targets=targets,
                                          dic=dic)

            # create toffoli
            toffoliId = AQP.generateToffoli(sources=sources, target=i, dic=dic)

            idList.append([setTrueId, toffoliId, setTrueId])

            targetList1[i] = targetList2[i]

        # generate the last path concatenating all
        path = []

        for i in idList:
            path += i

        for i in reversed(idList[:-1]):
            path += i

        return path
 def __init__(self, id, matrix, nQubits, path, targets):
     Special.__init__(self,
                      id=id,
                      matrix=matrix,
                      nQubits=nQubits,
                      path=path,
                      name="Oracle" + str(nQubits) + "_" +
                      str(QuantumMath.codingQubits(targets)))
     self.targets = QuantumMath.codingQubits(targets)
Example #4
0
def generateGate(index, nQubits, dic):
    Debug.debug(str(index) + " ; " + str(nQubits), DebugLevel.Function)

    array = []
    for i in range(nQubits):
        array.append(i)

    if index == 0:
        return AQP.generateBasic(standarGate=StandarGate.X,
                                 targets=array,
                                 dic=dic)

    elif index == 1:
        return AQP.generateXnot(source=0, target=nQubits - 1, dic=dic)

    elif index == 2:
        return AQP.generateBasicTurn(target=nQubits - 1,
                                     angle=math.pi / 2,
                                     turnType=TurnType.X,
                                     dic=dic)

    elif index == 3:
        return AQP.generateCondTurn(turnType=TurnType.X,
                                    target=nQubits - 1,
                                    source=nQubits - 2,
                                    angle=math.pi / 2,
                                    dic=dic)

    elif index == 4:
        return AQP.generateMultipleTurn(turnType=TurnType.X,
                                        target=nQubits - 1,
                                        sources=array[:-1],
                                        angle=math.pi / 2,
                                        dic=dic)

    elif index == 5:
        return AQP.generateToffoli(target=nQubits - 1,
                                   sources=array[:-1],
                                   dic=dic)

    elif index == 6:
        return AQP.generateSpecialTurn(a=1j, b=-1, dic=dic)

    elif index == 7:
        return AQP.generateRowReverse(target1=1,
                                      target2=2**nQubits - 2,
                                      dic=dic)

    elif index == 8:
        matrix = QuantumMath.getOracleMatrix(
            nQubits=nQubits, targets=[0, nQubits, 2**nQubits - 1])
        return (AQP.generateSpecial(name="oracle", matrix=matrix,
                                    dic=dic), matrix)

    elif index == 9:
        matrix = QuantumMath.getAmplitudAmplifier(nQubits=nQubits)
        return (AQP.generateSpecial(name="aa", matrix=matrix, dic=dic), matrix)
    def generateSpecialTurnPath(a, b, dic):

        module = QuantumMath.vectorModule([a, b])

        # normalizing parameters
        a /= module
        b /= module

        # calculating theta x and y
        theta = math.asin(QuantumMath.complexModule(b))
        y = cmath.phase(b)
        x = cmath.phase(a)

        lastQubit = dic.getNQubits() - 1
        sourceQubits = []
        for i in range(lastQubit):
            sourceQubits.append(i)

        firstGateId = AQP.generateMultipleTurn(turnType=TurnType.Z,
                                               target=lastQubit,
                                               sources=sourceQubits,
                                               angle=(-y + x + math.pi),
                                               dic=dic)

        secondGateId = AQP.generateMultipleTurn(turnType=TurnType.X,
                                                target=lastQubit,
                                                sources=sourceQubits,
                                                angle=theta * 2,
                                                dic=dic)

        thirdGateId = AQP.generateMultipleTurn(turnType=TurnType.Z,
                                               target=lastQubit,
                                               sources=sourceQubits,
                                               angle=(y + x),
                                               dic=dic)

        lastCondId = AQP.generateMultipleTurn(
            turnType=TurnType.Z,
            target=lastQubit,
            sources=sourceQubits,
            angle=QuantumMath.inverseAngle(x),
            dic=dic)

        # is the same with Toffoli or last qubit X
        #allToffoliId = AQP.generateToffoli(target=lastQubit, sources=sourceQubits, dic=dic)
        allToffoliId = AQP.generateBasic(standarGate=StandarGate.X,
                                         targets=[lastQubit],
                                         dic=dic)

        return [
            firstGateId, secondGateId, thirdGateId, lastCondId, allToffoliId,
            lastCondId, allToffoliId
        ]
    def generateBasicMatrix(standarGate, targets, nQubits):

        matrixIdentity = QuantumMath.getStdMatrix("I")
        matrixGate = QuantumMath.getStdMatrix(standarGate.name)
        matrixList = []

        for i in range(nQubits):
            if i in targets:
                matrixList.append(matrixGate)
            else:
                matrixList.append(matrixIdentity)

        return QuantumMath.tensorDot(matrixList)
    def generateBasicTurnMatrix(target, angle, turnType, nQubits):

        matrixIdentity = QuantumMath.getStdMatrix("I")
        matrixGate = QuantumMath.getStdTurnMatrix(turnType, angle)
        matrixList = []

        for i in range(nQubits):
            if i == target:
                matrixList.append(matrixGate)
            else:
                matrixList.append(matrixIdentity)

        return QuantumMath.tensorDot(matrixList)
    def generateCondTurnPath(turnType, target, source, angle, dic):

        # xnot
        xnotId = AQP.generateXnot(source=source, target=target, dic=dic)

        # turn
        inverseTurnId = AQP.generateBasicTurn(target=target,
                                              angle=QuantumMath.inverseAngle(
                                                  angle / 2),
                                              turnType=turnType,
                                              dic=dic)
        turnId = AQP.generateBasicTurn(target=target,
                                       angle=angle / 2,
                                       turnType=turnType,
                                       dic=dic)

        # with Z turn it need a recalculation
        if turnType == TurnType.Z:
            turnIdSource = AQP.generateBasicTurn(target=source,
                                                 angle=angle / 2,
                                                 turnType=turnType,
                                                 dic=dic)
            return [xnotId, inverseTurnId, xnotId, turnId, turnIdSource]

        else:
            #return [xnotId, inverseTurnId, xnotId, turnId]
            return [turnId, xnotId, inverseTurnId, xnotId]
 def __init__(self, id, matrix, nQubits, path, target, sources):
     Conditional.__init__(self,
                          id=id,
                          matrix=matrix,
                          path=path,
                          target=target,
                          nQubits=nQubits)
     self.sourcesCode = QuantumMath.codingQubits(sources)
    def generateMatrixFromPath(path, dic):

        matrixList = []

        for i in path:
            matrixList.append(dic.getGate(i).getMatrix())
        matrixList.reverse()
        return QuantumMath.matrixDot(matrixList)
 def getStringTypedPerQubit(self):
     l = []
     targets = QuantumMath.decodingQubits(self.targetsCode)
     for i in range(self.nQubits):
         if i in targets:
             l.append((QubitStringType.Target, self.standarGate.name))
         else:
             l.append((QubitStringType.Empty, ""))
     return (len(self.standarGate.name), l)
 def getStringTypedPerQubit(self):
     l = []
     sources = QuantumMath.decodingQubits(self.sourcesCode)
     for i in range(self.nQubits):
         if i in sources:
             l.append((QubitStringType.Source, ""))
         else:
             l.append((QubitStringType.Empty, ""))
     l[self.target] = (QubitStringType.Target, "(X)")
     return (3, l)
 def getStringTypedPerQubit(self):
     l = []
     st = printTurn(self.turnType, self.angle)
     sources = QuantumMath.decodingQubits(self.sourcesCode)
     for i in range(self.nQubits):
         if i in sources:
             l.append((QubitStringType.Source, ""))
         else:
             l.append((QubitStringType.Empty, ""))
     l[self.target] = (QubitStringType.Target, st)
     return (len(st), l)
    def getAsm(self, compress=False):
        stCom = Assembler.comment("Std Gate - " + self.standarGate.name +
                                  " targets: " + str(self.targetsCode))
        st = ""
        for i in QuantumMath.decodingQubits(self.targetsCode):
            st += Assembler.writeStdGate(standarGate=self.standarGate,
                                         target=i,
                                         nQubits=self.nQubits)

        if compress:
            return st
        else:
            return stCom + st + stCom + "\n"
Example #15
0
def generateGate(index, rowReverse, nQubits, dic):
    Debug.debug(str(index) + " ; " + str(nQubits), DebugLevel.Function)

    if rowReverse:
        return AQP.generateRowReverse(target1=0, target2=index, dic=dic)

    else:
        matrix = QuantumMath.getOracleMatrix(nQubits=nQubits, targets=[]) #generate a diagonal matrix
        matrix[0,0] = 1/math.sqrt(2)
        matrix[0,index] = 1/math.sqrt(2)
        matrix[index,0] = 1/math.sqrt(2)
        matrix[index,index] = -1/math.sqrt(2)
        return AQP.generateSpecial(name="2superpoitionGate", matrix=matrix, dic=dic)
    def generateXnotMatrix(source, target, nQubits):

        array = []
        o2 = 2**(nQubits - source - 1)
        t2 = 2**(nQubits - target - 1)
        q2 = 2**nQubits
        for i in range(q2):
            #buscamos los bits que nos conciernen en este caso
            bo = (i // o2) % 2
            if bo == 1:
                to = (i // t2) % 2
                if to == 0:
                    n = i + t2
                else:
                    n = i - t2
            else:
                n = i

            newArray = np.zeros(q2, dtype=complex)
            newArray[n] = 1

            array.append(newArray)

        return QuantumMath.generateMatrixFromBasicEquations(nQubits, array)
    def generateMultipleTurnPath(turnType, target, sources, angle, dic):

        # if there is just one source, is like a condTurn
        if len(sources) == 1:
            return [
                AQP.generateCondTurn(turnType=turnType,
                                     target=target,
                                     source=sources[0],
                                     angle=angle,
                                     dic=dic)
            ]

        # if there is two sources the implementation in automatic
        elif len(sources) == 2:

            nAngle = angle / 2

            # conditional turn
            condTurnId = AQP.generateCondTurn(turnType=turnType,
                                              target=target,
                                              source=sources[1],
                                              angle=nAngle,
                                              dic=dic)

            # xnot
            xnotId = AQP.generateXnot(source=sources[0],
                                      target=sources[1],
                                      dic=dic)

            # conditional turn inverse
            condTurnInvId = AQP.generateCondTurn(
                turnType=turnType,
                target=target,
                source=sources[1],
                angle=QuantumMath.inverseAngle(nAngle),
                dic=dic)

            # conditional turn from above
            condTurnAboveId = AQP.generateCondTurn(turnType=turnType,
                                                   target=target,
                                                   source=sources[0],
                                                   angle=nAngle,
                                                   dic=dic)

            #added to path
            return [condTurnId, xnotId, condTurnInvId, xnotId, condTurnAboveId]

        else:

            nAngle = angle / 2

            path = []

            # multiple n-1 sources
            multipleId = AQP.generateMultipleTurn(turnType=turnType,
                                                  target=target,
                                                  sources=sources[1:],
                                                  angle=nAngle,
                                                  dic=dic)

            path.append(multipleId)

            # create xnot to every qubit source from first source
            pathXnot = []
            for qubitAux in sources[1:]:

                # xnot
                xnotId = AQP.generateXnot(source=sources[0],
                                          target=qubitAux,
                                          dic=dic)

                #added to path
                pathXnot.append(xnotId)

            path += pathXnot

            # multiple n-1 sources
            multipleInvId = AQP.generateMultipleTurn(
                turnType=turnType,
                target=target,
                sources=sources[1:],
                angle=QuantumMath.inverseAngle(nAngle),
                dic=dic)

            path.append(multipleInvId)

            # redo xnots
            path += pathXnot

            # negate last qubit
            negateId = AQP.generateBasic(standarGate=StandarGate.X,
                                         targets=[sources[-1]],
                                         dic=dic)

            path.append(negateId)

            # x not from last qubit
            pathInverseXnot = []
            for qubitAux in sources[1:-1]:

                # xnot
                xnotId = AQP.generateXnot(source=sources[-1],
                                          target=qubitAux,
                                          dic=dic)

                #added to path
                pathInverseXnot.append(xnotId)

            path += pathInverseXnot

            # create the new multi conditional
            multiLowId = AQP.generateMultipleTurn(turnType=turnType,
                                                  target=target,
                                                  sources=sources[:-1],
                                                  angle=nAngle,
                                                  dic=dic)

            path.append(multiLowId)

            # redo the negation
            path += pathInverseXnot
            path.append(negateId)

            return path
Example #18
0
    def getIdBasic(self, standarGate, targets):

        return self.getId(
            GateType.Basic,
            [standarGate, QuantumMath.codingQubits(targets)])
Example #19
0
    def addIdToffoli(self, gate, target, sources):

        return self.addGate(gate, GateType.Toffoli,
                            [target, QuantumMath.codingQubits(sources)])
Example #20
0
    def addIdMultipleTurn(self, gate, turnType, target, sources, angle):

        return self.addGate(
            gate, GateType.MultipleTurn,
            [turnType, target,
             QuantumMath.codingQubits(sources), angle])
Example #21
0
    def addIdBasic(self, gate, standarGate, targets):

        return self.addGate(
            gate, GateType.Basic,
            [standarGate, QuantumMath.codingQubits(targets)])
Example #22
0
    def getIdMultipleTurn(self, turnType, target, sources, angle):

        return self.getId(
            GateType.MultipleTurn,
            [turnType, target,
             QuantumMath.codingQubits(sources), angle])
    def generateSpecialPath(name, matrix, dic):

        nRows = 2**dic.getNQubits()
        step = AQP.getNextStep(matrix=matrix, step=[-1, -1], nRows=nRows)

        lastRow = nRows - 1
        penLastRow = nRows - 2

        idPath = []

        while (step):

            #print(matrix)
            #print(step)

            a = 0
            b = 0

            if step[0] == step[1]:
                #diagonal

                if step[0] == penLastRow:
                    #last special turn

                    # create the special turn matrix with the conjugate values
                    a = QuantumMath.conjugate(matrix[step[0], step[0]])

                    specialTurnId = AQP.generateSpecialTurn(a=a, b=0, dic=dic)

                    #added to path
                    idPath = [specialTurnId] + idPath

                else:
                    rowRevertPenLastId = AQP.generateRowReverse(
                        target1=step[0], target2=penLastRow, dic=dic)

                    # create the special turn matrix with the conjugate values
                    a = QuantumMath.conjugate(matrix[step[0], step[0]])

                    specialTurnId = AQP.generateSpecialTurn(a=a, b=0, dic=dic)

                    #added to path
                    idPath = [
                        rowRevertPenLastId, specialTurnId, rowRevertPenLastId
                    ] + idPath

            else:
                # create the row reversion
                rowRevertPenLastId = AQP.generateRowReverse(target1=step[0],
                                                            target2=penLastRow,
                                                            dic=dic)

                rowRevertLastId = AQP.generateRowReverse(target1=step[1],
                                                         target2=lastRow,
                                                         dic=dic)

                # create the special turn matrix with the conjugate values
                a = QuantumMath.conjugate(matrix[step[0], step[0]])
                b = QuantumMath.conjugate(matrix[step[1], step[0]])

                specialTurnId = AQP.generateSpecialTurn(a=a, b=b, dic=dic)

                #! IS IMPORTANT THE ORDEN OF THE REVERSER
                #added to path
                idPath = [
                    rowRevertLastId, rowRevertPenLastId, specialTurnId,
                    rowRevertPenLastId, rowRevertLastId
                ] + idPath

            matrix = AQP.nextMatrix(matrix=matrix,
                                    step=step,
                                    a=a,
                                    b=b,
                                    nRows=nRows)
            #print(matrix)
            #print("\n\n")

            step = AQP.getNextStep(matrix=matrix, step=step, nRows=nRows)

        # Last binary matrix should be a Z

        #get phase for last value
        phase = QuantumMath.getPhase(matrix[nRows - 1, nRows - 1])

        if phase != 0:

            sources = []
            for i in range(dic.getNQubits() - 1):
                sources.append(i)

            # added last turn Z
            turnId = AQP.generateMultipleTurn(turnType=TurnType.Z,
                                              target=dic.getNQubits() - 1,
                                              sources=sources,
                                              angle=phase,
                                              dic=dic)

            idPath = [turnId] + idPath

        return idPath
def printTurn(turnType, angle, decimals=2):
    return turnType.name + str(QuantumMath.round(angle, decimals))
Example #25
0
    def getIdToffoli(self, target, sources):

        return self.getId(GateType.Toffoli,
                          [target, QuantumMath.codingQubits(sources)])
 def __init__(self, id, matrix, nQubits, standarGate, targets):
     Standar.__init__(self, id=id, matrix=matrix, nQubits=nQubits)
     self.standarGate = standarGate
     self.targetsCode = QuantumMath.codingQubits(targets)
Example #27
0
    def addIdOracle(self, gate, targets):

        return self.addGate(gate, GateType.Oracle,
                            QuantumMath.codingQubits(targets))
Example #28
0
    def getIdOracle(self, targets):

        return self.getId(GateType.Oracle, QuantumMath.codingQubits(targets))