R/export2qiskit.R

Defines functions export2qiskit

Documented in export2qiskit

#' export2qiskit
#'
#' Export to IBM's Qiskit
#' 
#' @description
#' export a circuit to IBM's qiskit python format. Note that only
#' gates can be exported where the correspondence in qiskit is known
#' and well defined. Qiskit can then be used for IBM's QASM to run on
#' real hardware.
#'
#' @details
#' Currently the following gates can be exported: H, X, Y, Z, S,
#' Tgate, Rz, Rx, Ry, CNOT, SWAP, CCNOT, CSWAP, measure.
#' 
#' @param object a qstate object
#' @param varname character. The name of the circuit variable
#' @param filename character. The filename of the textfile where to store the circuit
#' @param append boolean. Whether or not to append to the file. For this the file has to exist.
#' @param import boolean. Shall numpy and qiskit be loaded explicitly?
#'
#' @include state.R
#'
#' @references
#' https://qiskit.org/documentation/
#'
#' @details
#' note that only standard gates can be exported, not self defined ones.
#' The function will draw a warning in case a gate cannot be exported
#' and indicate it in the output file.
#' 
#' @return
#' nothing is returned, but a file is created.
#' 
#' @examples
#' x <- qstate(2)
#' x <- H(1) * x
#' x <- X(2) * x
#' x <- CNOT(c(1,2)) * x
#' export2qiskit(measure(x,1)$psi)
#' cat(readLines("circuit.py"), sep = '\n')
#' file.remove("circuit.py")
#' 
#' @export
export2qiskit <- function(object, varname="qc", filename="circuit.py", append=FALSE, import=FALSE) {
  if(!append) file.create(filename)
  olines <- c("# automatically generated by qsimulatR")
  if(import){
    olines <- c(olines, "import numpy as np",
                "from qiskit import(QuantumCircuit, execute, Aer)",
                "from qiskit.visualization import plot_histogram",
                "simulator = Aer.get_backend('qasm_simulator')")
  }
  if(object@circuit$ncbits == 0) {
    olines <- c(olines, paste0(varname, " = QuantumCircuit(", object@nbits, ")"))
  }
  else {
    olines <- c(olines, paste0(varname, " = QuantumCircuit(", object@nbits, ",", object@circuit$ncbits, ")"))
  }

  gates <- object@circuit$gatelist
  ngates <- length(gates)
  if(ngates > 0) {
    for(i in c(1:ngates)) {
      set.bits <- gates[[i]]$bits[!is.na(gates[[i]]$bits)] - 1
      op.bits <- paste0(set.bits, collapse=", ")

      op.gate <- switch(gates[[i]]$type,
                        "H" = "h",
                        "X" = "x",
                        "Y" = "y",
                        "Z" = "z",
                        "S" = "s",
                        "Tgate" = "t",
                        "CNOT" = "cx",
                        "SWAP" = "swap",
                        "CCNOT" = "ccx",
                        "CSWAP" = "cswap",
                        "measure" = "measure",
                        {
                          if(gates[[i]]$type == "Rz" || grepl("^R[0-9]+", gates[[i]]$type)){
                            if(gates[[i]]$controlled) "crz"
                            else "rz"
                          }
                          else if(gates[[i]]$type == "Rx") {
                            if(gates[[i]]$controlled) "crx"
                            else "rx"
                          }
                          else if(gates[[i]]$type == "Ry") {
                            if(gates[[i]]$controlled) "cry"
                            else "ry"
                          }
                          else{
                            warning("Gate of type '", gates[[i]]$type, "' is not supported!")
                            olines <- c(olines, paste0("# ", varname, ".", gates[[i]]$type, "(", op.bits,
                                                       ") ## WARNING: Not properly exported, interpret as pseudocode!"))
                            next
                          }
                        })

      op.gate <- paste0(op.gate, "(")
      if(gates[[i]]$type == "Rx" || gates[[i]]$type == "Ry" || gates[[i]]$type == "Rz" || grepl("^R[0-9]+", gates[[i]]$type))
        op.gate <- paste0(op.gate, gates[[i]]$angle, ", ")

      olines <- c(olines, paste0(varname, ".", op.gate, op.bits, ")"))
    }
  }
  fc <- NULL
  if(append) fc <- file(filename, open="at")
  else fc <- file(filename)
  writeLines(text=olines, con=fc)
  close(fc)
}

Try the qsimulatR package in your browser

Any scripts or data that you put into this service are public.

qsimulatR documentation built on Oct. 16, 2023, 5:06 p.m.