diff --git a/README.md b/README.md
index f90cf9a..0761ae9 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,36 @@
# CMU_Coin-flipping_Experience
-A Coin Flipping machine.
+A Coin Flipping machine inspired by the IBM Q Experience.
-Usage: java -jar xxx.jar \ \ \
+15-459 Assignment
+
+## Usage
+
+java -jar xxx.jar \ \ \
+
+
+## Available operators:
-Available operators:
Tester: Run a simulation and print results
-Prob0Init: Print the probabilities of each possible outcome
-
-Input commands:
-$$
- \begin{align*}
- \text{Flip} & & i & & \text{(randomly set coin~$i$ to $0$ or $1$ with probability $1/2$ each)} \\
- \text{Not} & & i & & \text{(turn over the $i$th coin; i.e., deterministically reverse its $0$/$1$ status)} \\
- \text{CNot} & & i\ j & & \text{(if coin~$i$ is $1$ (Tails) then do a Not on coin~$j$, else do nothing)}\\
- \text{CSwap} & & i\ j\ k & & \text{(if coin~$i$ is $1$ (Tails) then swap the values of coins $j$ and $k$)}
- \end{align*}
- \begin{align*}
- \text{CCNot} & & i\ j \ k& & \text{(if coins~$i$ and $j$ are \emph{both} $1$ then do `Not~$k$', else do nothing)}\\
- \text{GenFlip} & & i\ p & & \text{(set coin~$i$ to $0$ with probability $1-p$, to $1$ with probability $p$)} \\
- \text{Gen1Bit} & & i\ p\ q & & \text{(if coin~$i$ is $0$ then make it~$1$ with probability $p$,\qquad}\\
- & & & & \text{else if coin~$i$ is $1$ then make it~$0$ with probability $q$)}
- \end{align*}
-$$
+
+Prob0Init: Print the probabilities of each possible outcome (0 initialized)
+
+ProbAllInit: Print the probabilities of each coin being 1 for all initializations
+
+
+## Input commands:
+
+```
+$$ \begin{align*}
+ \text{Flip} & & i & & \text{(randomly set coin~$i$ to $0$ or $1$ with probability $1/2$ each)} \\
+ \text{Not} & & i & & \text{(turn over the $i$th coin; i.e., deterministically reverse its $0$/$1$ status)} \\
+ \text{CNot} & & i\ j & & \text{(if coin~$i$ is $1$ (Tails) then do a Not on coin~$j$, else do nothing)}\\
+ \text{CSwap} & & i\ j\ k & & \text{(if coin~$i$ is $1$ (Tails) then swap the values of coins $j$ and $k$)}
+\end{align*}
+\begin{align*}
+ \text{CCNot} & & i\ j \ k& & \text{(if coins~$i$ and $j$ are \emph{both} $1$ then do `Not~$k$', else do nothing)}\\
+ \text{GenFlip} & & i\ p & & \text{(set coin~$i$ to $0$ with probability $1-p$, to $1$ with probability $p$)} \\
+ \text{Gen1Bit} & & i\ p\ q & & \text{(if coin~$i$ is $0$ then make it~$1$ with probability $p$,\qquad}\\
+ & & & & \text{else if coin~$i$ is $1$ then make it~$0$ with probability $q$)}
+\end{align*} $$
+```
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index 9092efc..2f54022 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,7 +1,9 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
plugins {
kotlin("jvm") version "1.4.10"
+ id("com.github.johnrengelman.shadow") version "6.0.0"
}
group = "com.dedztbh"
version = "1.0-SNAPSHOT"
@@ -16,8 +18,25 @@ repositories {
dependencies {
implementation("org.deeplearning4j:deeplearning4j-core:${dl4jVersion}")
implementation("org.nd4j:nd4j-native-platform:${dl4jVersion}")
- testImplementation(kotlin("test-junit"))
+ implementation("org.slf4j:slf4j-nop:1.7.13")
+// testImplementation(kotlin("test-junit"))
}
tasks.withType() {
kotlinOptions.jvmTarget = "1.8"
}
+
+tasks {
+ named("shadowJar") {
+ archiveBaseName.set("cmu_coin_flipping_experience")
+ mergeServiceFiles()
+ manifest {
+ attributes(mapOf("Main-Class" to "MainKt"))
+ }
+ }
+}
+
+tasks {
+ build {
+ dependsOn(shadowJar)
+ }
+}
\ No newline at end of file
diff --git a/input.txt b/input.txt
index ad7a09e..b8052e4 100644
--- a/input.txt
+++ b/input.txt
@@ -1,8 +1,5 @@
-GenFlip 0 0.1
GenFlip 1 0.3
-GenFlip 2 0.5
GenFlip 3 0.7
-GenFlip 4 0.9
CNot 1 2
CSwap 3 4 0
CCNot 1 2 3
diff --git a/src/main/kotlin/operator/Prob0Init.kt b/src/main/kotlin/operator/Prob0Init.kt
index 81898aa..efd3603 100644
--- a/src/main/kotlin/operator/Prob0Init.kt
+++ b/src/main/kotlin/operator/Prob0Init.kt
@@ -1,7 +1,7 @@
package operator
+import allStates
import org.nd4j.linalg.api.ndarray.INDArray
-import kotlin.math.pow
/**
* Created by DEDZTBH on 2020/09/15.
@@ -47,8 +47,7 @@ class Prob0Init(N: Int) : ProbFinder(N) {
override fun printResult() {
val probs = eval(getZeroVec())
- repeat(2.0.pow(N).toInt()) {
- val endState = IntArray(N) { i -> (it shr i) and 1 }.apply { reverse() }
+ allStates(N).forEach { endState ->
var prob = 1.0
endState.forEach { i ->
prob *= if (i > 0) probs.getDouble(i) else (1.0 - probs.getDouble(i))
diff --git a/src/main/kotlin/operator/ProbAllInit.kt b/src/main/kotlin/operator/ProbAllInit.kt
new file mode 100644
index 0000000..71990ac
--- /dev/null
+++ b/src/main/kotlin/operator/ProbAllInit.kt
@@ -0,0 +1,81 @@
+package operator
+
+import allStates
+import org.nd4j.linalg.api.buffer.DataType
+import org.nd4j.linalg.api.ndarray.INDArray
+import org.nd4j.linalg.factory.Nd4j
+
+/**
+ * Created by DEDZTBH on 2020/09/15.
+ * Project CMU_Coin-flipping_Experience
+ */
+class ProbAllInit(N: Int) : ProbFinder(N) {
+ fun eval(probs: INDArray): INDArray {
+ operations.forEach {
+ it.apply {
+ when (this) {
+ is Matrix -> {
+ probs.muliRowVector(opVec)
+ probs.addiRowVector(opBias)
+ }
+ is CNot -> {
+ val i = i.toLong()
+ val j = j.toLong()
+ val x = probs.getColumn(i)
+ val y = probs.getColumn(j)
+ //(1.0 - x) * y + x * (1.0 - y)
+ val newCol = x.mul(y).mul(-2.0).add(x).add(y)
+ probs.putColumn(this.j, newCol)
+ }
+ is CSwap -> {
+ val i = i.toLong()
+ val j = j.toLong()
+ val k = k.toLong()
+ val x = probs.getColumn(i)
+ val y = probs.getColumn(j)
+ val z = probs.getColumn(k)
+ val xy = x.mul(y)
+ val xz = x.mul(z)
+ //(1.0 - x) * y + x * z
+ probs.putColumn(this.j, y.sub(xy).add(xz))
+ //(1.0 - x) * z + x * y
+ probs.putColumn(this.k, z.sub(xz).add(xy))
+ }
+ is CCNot -> {
+ val i = i.toLong()
+ val j = j.toLong()
+ val k = k.toLong()
+ val x = probs.getColumn(i)
+ val y = probs.getColumn(j)
+ val z = probs.getColumn(k)
+ //(1.0 - x) * (1.0 - y)
+ val probBoth0 = x.mul(y).sub(x).sub(y).add(1.0)
+ //probBoth0 * z + (1.0 - probBoth0) * (1.0 - z)
+ probs.putColumn(this.k, probBoth0.mul(z).mul(2.0).sub(probBoth0).sub(z).add(1.0))
+ }
+ is Gen1Bit -> {
+ val i = i.toLong()
+ val x = probs.getColumn(i)
+ val xx = x.mul(x)
+ val p_comp = 1.0 - p
+ probs.putColumn(
+ this.i,
+ //x * (1.0 - q) * x + (1.0 - x) * (p + (1.0 - p) * x)
+ //= xx(1-q) + p + (1-p)x - xp - xx(1-p)
+ xx.mul(1.0 - q).add(p).add(x.mul(p_comp)).sub(x.mul(p)).sub(xx.mul(p_comp))
+ )
+ }
+ }
+ }
+ }
+ return probs
+ }
+
+ override fun printResult() {
+ val probs = eval(
+ // a 2^n by n matrix
+ Nd4j.create(allStates(N)).castTo(DataType.DOUBLE)
+ )
+ println(probs)
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/util.kt b/src/main/kotlin/util.kt
index 1a721c1..a8cdb21 100644
--- a/src/main/kotlin/util.kt
+++ b/src/main/kotlin/util.kt
@@ -1,5 +1,6 @@
import java.io.BufferedReader
import java.util.*
+import kotlin.math.pow
/**
* Created by DEDZTBH on 2020/09/15.
@@ -17,4 +18,9 @@ fun read(): String {
fun readInt() = read().toInt()
fun readDouble() = read().toDouble()
+fun allStates(n: Int) =
+ Array(2.0.pow(n).toInt()) {
+ IntArray(n) { i -> (it shr i) and 1 }.apply { reverse() }
+ }
+
lateinit var reader: BufferedReader
\ No newline at end of file