Skip to content

Commit

Permalink
v1.1
Browse files Browse the repository at this point in the history
- Add alias "H" for Hadamard
- Measure now won't terminate read
- Code refactor
  • Loading branch information
dedztbh committed Sep 25, 2020
1 parent f77f02a commit 6f97c87
Show file tree
Hide file tree
Showing 13 changed files with 242 additions and 141 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ TFinder: Similar to Tester, but only print the circuit's matrix.
AllInit: Similar to Tester, but run for each possible initial state (2^N of them).

## Commands
i, j, k are indicies of qubit. (0-indexed)

- Not i
- Hadamard i
+ You can also use "H" instead of "Hadamard"
- CNot i j
- Swap i j
- CCNot i j k
Expand All @@ -40,10 +42,10 @@ AllInit: Similar to Tester, but run for each possible initial state (2^N of them
- TDag i
- SqrtNot i
- SqrtNotDag i
- SqrtSwap i j (Not implemented yet)
- SqrtSwap i j
+ Not implemented yet
- Rot i deg
+ Rotate qubit counterclockwise by degree, not rad
- Measure n
+ Measures the joint qubit state n times using standard basis
+ Only works when using Tester
+ Will end command read
+ Measures the joint qubit state n times using the standard basis
+ Only works when using Tester
3 changes: 2 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {
id("com.github.johnrengelman.shadow") version "6.0.0"
}
group = "com.dedztbh"
version = "1.0"
version = "1.1"

val ejmlVersion = "0.39"

Expand All @@ -17,6 +17,7 @@ repositories {
dependencies {
implementation("org.ejml:ejml-core:${ejmlVersion}")
implementation("org.ejml:ejml-zdense:${ejmlVersion}")
testImplementation("org.ejml:ejml-cdense:${ejmlVersion}")
}

tasks.withType<KotlinCompile> {
Expand Down
2 changes: 0 additions & 2 deletions src/main/kotlin/main.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import operator.Operator
import util.read
import util.reader
import java.io.File

/**
Expand Down
61 changes: 61 additions & 0 deletions src/main/kotlin/matrix/const.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package matrix

/**
* Created by DEDZTBH on 2020/09/25.
* Project KuantumCircuitSim
*/

/** 2^(-1/2) */
const val HALF_AMPL = 0.70710678118654757273731092936941422522068023681640625

/** Don't change these constant matrices! */
val NOT = CMatrix(
arrayOf(
doubleArrayOf(0.0, 0.0, 1.0, 0.0),
doubleArrayOf(1.0, 0.0, 0.0, 0.0)
)
)
val H = CMatrix(
arrayOf(
doubleArrayOf(HALF_AMPL, 0.0, HALF_AMPL, 0.0),
doubleArrayOf(HALF_AMPL, 0.0, -HALF_AMPL, 0.0)
)
)
val I1 = COps.identity(1)
val I2 = COps.identity(2)

val KET0 = CMatrix(arrayOf(doubleArrayOf(1.0, 0.0), doubleArrayOf(0.0, 0.0)))
val KET1 = CMatrix(arrayOf(doubleArrayOf(0.0, 0.0), doubleArrayOf(1.0, 0.0)))

val KETBRA0 = COps.diag(1.0, 0.0, 0.0, 0.0)
val KETBRA1 = COps.diag(0.0, 0.0, 1.0, 0.0)
val SQRT_NOT = CMatrix(
arrayOf(
doubleArrayOf(0.5, 0.5, 0.5, -0.5),
doubleArrayOf(0.5, -0.5, 0.5, 0.5),
)
)
val SQRT_NOT_DAG = CMatrix(2, 2).also {
COps.transposeConjugate(SQRT_NOT, it)
}
val Z = CMatrix(
arrayOf(
doubleArrayOf(1.0, 0.0, 0.0, 0.0),
doubleArrayOf(0.0, 0.0, -1.0, 0.0),
)
)
val S = CMatrix(
arrayOf(
doubleArrayOf(1.0, 0.0, 0.0, 0.0),
doubleArrayOf(0.0, 0.0, 0.0, 1.0),
)
)
val T = CMatrix(
arrayOf(
doubleArrayOf(1.0, 0.0, 0.0, 0.0),
doubleArrayOf(0.0, 0.0, HALF_AMPL, HALF_AMPL),
)
)
val TDag = CMatrix(2, 2).also {
COps.transposeConjugate(T, it)
}
94 changes: 15 additions & 79 deletions src/main/kotlin/util/matrix.kt → src/main/kotlin/matrix/op.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package util
package matrix

import org.ejml.UtilEjml
import org.ejml.data.Complex_F64
import org.ejml.data.MatrixSparse
import org.ejml.data.MatrixType
import org.ejml.data.ZMatrixRMaj
import org.ejml.dense.row.CommonOps_ZDRM
import org.ejml.ops.MatrixIO
import java.io.PrintStream
import java.text.DecimalFormat
Expand All @@ -17,16 +14,16 @@ import java.text.DecimalFormat
*/

/**
* Kronecker product of two ZDRM matrices
* Kronecker product of two complex matrices
*/
infix fun ZMatrixRMaj.kron(B: ZMatrixRMaj) = let { A ->
infix fun CMatrix.kron(B: CMatrix) = let { A ->
val numColsC = A.numCols * B.numCols
val numRowsC = A.numRows * B.numRows

val C = ZMatrixRMaj(numRowsC, numColsC)
val C = CMatrix(numRowsC, numColsC)

val acomplex = Complex_F64()
val bcomplex = Complex_F64()
val acomplex = CNumber()
val bcomplex = CNumber()
for (i in 0 until A.numRows) {
for (j in 0 until A.numCols) {
A.get(i, j, acomplex)
Expand All @@ -46,85 +43,24 @@ infix fun ZMatrixRMaj.kron(B: ZMatrixRMaj) = let { A ->
/**
* Convenient pure ops
*/
operator fun ZMatrixRMaj.plus(B: ZMatrixRMaj) =
ZMatrixRMaj(numRows, numCols).also { CommonOps_ZDRM.add(this, B, it) }
operator fun CMatrix.plus(B: CMatrix) =
CMatrix(numRows, numCols).also { COps.add(this, B, it) }

operator fun ZMatrixRMaj.times(B: ZMatrixRMaj) =
ZMatrixRMaj(numRows, B.numCols).also { CommonOps_ZDRM.mult(this, B, it) }
operator fun CMatrix.times(B: CMatrix) =
CMatrix(numRows, B.numCols).also { COps.mult(this, B, it) }


/**
* Useful constants
*/
typealias Matrix = ZMatrixRMaj
typealias Ops = CommonOps_ZDRM

/** 2^(-1/2) */
const val HALF_AMPL = 0.70710678118654757273731092936941422522068023681640625

/** Don't change these constant matrices! */
val NOT = Matrix(
arrayOf(
doubleArrayOf(0.0, 0.0, 1.0, 0.0),
doubleArrayOf(1.0, 0.0, 0.0, 0.0)
)
)
val H = Matrix(
arrayOf(
doubleArrayOf(HALF_AMPL, 0.0, HALF_AMPL, 0.0),
doubleArrayOf(HALF_AMPL, 0.0, -HALF_AMPL, 0.0)
)
)
val I1 = Ops.identity(1)
val I2 = Ops.identity(2)

val KET0 = Matrix(arrayOf(doubleArrayOf(1.0, 0.0), doubleArrayOf(0.0, 0.0)))
val KET1 = Matrix(arrayOf(doubleArrayOf(0.0, 0.0), doubleArrayOf(1.0, 0.0)))

val KETBRA0 = Ops.diag(1.0, 0.0, 0.0, 0.0)
val KETBRA1 = Ops.diag(0.0, 0.0, 1.0, 0.0)
val SQRT_NOT = Matrix(
arrayOf(
doubleArrayOf(0.5, 0.5, 0.5, -0.5),
doubleArrayOf(0.5, -0.5, 0.5, 0.5),
)
)
val SQRT_NOT_DAG = ZMatrixRMaj(2, 2).also {
Ops.transposeConjugate(SQRT_NOT, it)
}
val Z = Matrix(
arrayOf(
doubleArrayOf(1.0, 0.0, 0.0, 0.0),
doubleArrayOf(0.0, 0.0, -1.0, 0.0),
)
)
val S = Matrix(
arrayOf(
doubleArrayOf(1.0, 0.0, 0.0, 0.0),
doubleArrayOf(0.0, 0.0, 0.0, 1.0),
)
)
val T = Matrix(
arrayOf(
doubleArrayOf(1.0, 0.0, 0.0, 0.0),
doubleArrayOf(0.0, 0.0, HALF_AMPL, HALF_AMPL),
)
)
val TDag = ZMatrixRMaj(2, 2).also {
Ops.transposeConjugate(T, it)
}

/** Printing util */
object MyMatrixIO {
fun getMatrixType(mat: Matrix): String {
fun getMatrixType(mat: CMatrix): String {
return if (mat.type == MatrixType.UNSPECIFIED) {
mat.javaClass.simpleName
} else {
mat.type.name
}
}

fun printTypeSize(out: PrintStream, mat: Matrix) {
fun printTypeSize(out: PrintStream, mat: CMatrix) {
if (mat is MatrixSparse) {
val m = mat as MatrixSparse
out.println(
Expand All @@ -145,16 +81,16 @@ object MyMatrixIO {
}
}

fun ZMatrixRMaj.printFancy2(
fun CMatrix.printFancy2(
out: PrintStream = System.out,
length: Int = MatrixIO.DEFAULT_LENGTH,
allssr: List<String>
) = this.let { mat ->
) = let { mat ->
MyMatrixIO.printTypeSize(out, mat)
val format = DecimalFormat("#")
val builder = StringBuilder(length)
val cols = mat.numCols
val c = Complex_F64()
val c = CNumber()
var i = 0
for (y in 0 until mat.numRows) {
for (x in 0 until cols) {
Expand Down
14 changes: 14 additions & 0 deletions src/main/kotlin/matrix/type.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package matrix

import org.ejml.data.Complex_F64
import org.ejml.data.ZMatrixRMaj
import org.ejml.dense.row.CommonOps_ZDRM

/**
* Created by DEDZTBH on 2020/09/25.
* Project KuantumCircuitSim
*/

typealias CMatrix = ZMatrixRMaj
typealias COps = CommonOps_ZDRM
typealias CNumber = Complex_F64
2 changes: 1 addition & 1 deletion src/main/kotlin/operator/AllInit.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package operator

import util.*
import matrix.*


/**
Expand Down
20 changes: 11 additions & 9 deletions src/main/kotlin/operator/TFinder.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package operator

import util.*
import matrix.*
import readDouble
import readInt
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.pow
Expand All @@ -25,7 +27,7 @@ open class TFinder(val N: Int) : Operator {
val allssr = alls.map { arr -> "|${arr.reversed().joinToString("")}>" }

val jointStateSize = alls.size
val IN2 = Ops.identity(jointStateSize)
val IN2 = COps.identity(jointStateSize)

var opMatrix = IN2

Expand All @@ -35,19 +37,19 @@ open class TFinder(val N: Int) : Operator {
}
}

val matrix0CtrlCache = Array(N) { HashMap<Matrix, Matrix>() }
fun get0CtrlMatrix(i: Int, mat: Matrix, cache: Boolean = true): Matrix {
val matrix0CtrlCache = Array(N) { HashMap<CMatrix, CMatrix>() }
fun get0CtrlMatrix(i: Int, mat: CMatrix, cache: Boolean = true): CMatrix {
if (cache) matrix0CtrlCache[i][mat]?.let { return it }
val res = IKronTable[i] kron mat kron IKronTable[N - i - 1]
if (cache) matrix0CtrlCache[i][mat] = res
return res
}

val matrix1CtrlCache = Array(N) { Array(N) { HashMap<Matrix, Matrix>() } }
val matrix1CtrlCache = Array(N) { Array(N) { HashMap<CMatrix, CMatrix>() } }

/** Control matrix generation based on this great article:
* http://www.sakkaris.com/tutorials/quantum_control_gates.html */
fun get1CtrlMatrix(i: Int, j: Int, mat: Matrix, cache: Boolean = true): Matrix {
fun get1CtrlMatrix(i: Int, j: Int, mat: CMatrix, cache: Boolean = true): CMatrix {
if (cache) matrix1CtrlCache[i][j][mat]?.let { return it }
val res = get0CtrlMatrix(i, KETBRA0) + when {
i < j -> IKronTable[i] kron KETBRA1 kron
Expand All @@ -62,7 +64,7 @@ open class TFinder(val N: Int) : Operator {
return res
}

fun getCCNotMatrix(i: Int, j: Int, k: Int): Matrix {
fun getCCNotMatrix(i: Int, j: Int, k: Int): CMatrix {
/** using Sleator-Weinfurter construction
* matrix is actually reverse order as graph */
val cnotij = get1CtrlMatrix(i, j, NOT)
Expand Down Expand Up @@ -94,7 +96,7 @@ open class TFinder(val N: Int) : Operator {
val i = readInt()
val newOp = when (cmd) {
"Not" -> get0CtrlMatrix(i, NOT)
"Hadamard" -> get0CtrlMatrix(i, H)
"Hadamard", "H" -> get0CtrlMatrix(i, H)
"CNot" -> get1CtrlMatrix(i, readInt(), NOT)
"Swap" -> {
/** https://algassert.com/post/1717
Expand Down Expand Up @@ -126,7 +128,7 @@ open class TFinder(val N: Int) : Operator {
val rad = readDouble() * PI / 180
val sine = sin(rad)
val cosine = cos(rad)
val rotMat = Matrix(
val rotMat = CMatrix(
arrayOf(
doubleArrayOf(cosine, 0.0, -sine, 0.0),
doubleArrayOf(sine, 0.0, cosine, 0.0)
Expand Down
14 changes: 9 additions & 5 deletions src/main/kotlin/operator/Tester.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package operator

import org.ejml.data.Complex_F64
import util.*
import matrix.CMatrix
import matrix.CNumber
import matrix.printFancy2
import matrix.times
import readInt
import upperBound
import kotlin.random.Random

/**
Expand All @@ -11,15 +15,15 @@ import kotlin.random.Random
class Tester(N: Int) : TFinder(N) {
/** 2^N by 1 column vector */
val jointState =
Matrix(jointStateSize, 1).apply { set(0, 0, 1.0, 0.0) }
CMatrix(jointStateSize, 1).apply { set(0, 0, 1.0, 0.0) }

override fun runCmd(cmd: String): Int {
if (cmd == "Measure") {
val i = readInt()
val results = opMatrix * jointState
val probs = mutableListOf(0.0)
val labels = mutableListOf<Int>()
val a = Complex_F64()
val a = CNumber()
for (j in 0 until results.numRows) {
results.get(0, j, a)
if (a.magnitude2 > 0) {
Expand All @@ -34,7 +38,7 @@ class Tester(N: Int) : TFinder(N) {
println(allssr[labels[index]])
}
println()
return 1
return 0
}
return super.runCmd(cmd)
}
Expand Down
Loading

0 comments on commit 6f97c87

Please sign in to comment.