Skip to content

Commit

Permalink
v1.1
Browse files Browse the repository at this point in the history
Changed matrix library to EJML
  • Loading branch information
dedztbh committed Sep 18, 2020
1 parent aa8ae6c commit 202d997
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 106 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -149,5 +149,7 @@ CMU_Coin-flipping_Experience.iws
CMU_Coin-flipping_Experience.main.iml
CMU_Coin-flipping_Experience.test.iml
gradle/
gradlew
gradlew.bat

input.txt
14 changes: 7 additions & 7 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
kotlin("jvm") version "1.4.10"
id("com.github.johnrengelman.shadow") version "6.0.0"
}
group = "com.dedztbh"
version = "1.0-SNAPSHOT"
version = "1.1"

val dl4jVersion = "1.0.0-beta7"
val ejmlVersion = "0.39"


repositories {
mavenCentral()
maven("https://dl.bintray.com/mipt-npm/scientifik")
}
dependencies {
implementation("org.deeplearning4j:deeplearning4j-core:${dl4jVersion}")
implementation("org.nd4j:nd4j-native-platform:${dl4jVersion}")
implementation("org.slf4j:slf4j-nop:1.7.13")
implementation("org.ejml:ejml-core:${ejmlVersion}")
implementation("org.ejml:ejml-kotlin:${ejmlVersion}")
implementation("org.ejml:ejml-fdense:${ejmlVersion}")
// testImplementation(kotlin("test-junit"))
}
tasks.withType<KotlinCompile>() {
Expand All @@ -32,6 +31,7 @@ tasks {
manifest {
attributes(mapOf("Main-Class" to "MainKt"))
}
minimize()
}
}

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

/**
Expand Down
58 changes: 34 additions & 24 deletions src/main/kotlin/operator/Prob0Init.kt
Original file line number Diff line number Diff line change
@@ -1,43 +1,52 @@
package operator

import allStates
import org.nd4j.linalg.api.ndarray.INDArray
import org.ejml.data.FMatrixRMaj
import org.ejml.dense.row.CommonOps_FDRM
import org.ejml.kotlin.plusAssign
import kotlin.math.pow

/**
* Created by DEDZTBH on 2020/09/15.
* Project CMU_Coin-flipping_Experience
*/

fun allStates(n: Int) =
Array(2.0.pow(n).toInt()) {
IntArray(n) { i -> (it shr i) and 1 }.apply { reverse() }
}

class Prob0Init(N: Int) : ProbFinder(N) {
fun eval(probs: INDArray): INDArray {
fun eval(probs: FMatrixRMaj): FMatrixRMaj {
operations.forEach {
it.apply {
when (this) {
is Matrix -> {
probs.muli(opVec)
probs.addi(opBias)
is MatrixOp -> {
CommonOps_FDRM.elementMult(probs, opVec)
probs += opBias
}
is CNot -> {
val x = probs.getDouble(i)
val y = probs.getDouble(j)
probs.putScalar(j.toLong(), (1.0 - x) * y + x * (1.0 - y))
val x = probs[i]
val y = probs[j]
probs[j] = (1f - x) * y + x * (1f - y)
}
is CSwap -> {
val x = probs.getDouble(i)
val y = probs.getDouble(j)
val z = probs.getDouble(k)
probs.putScalar(j.toLong(), (1.0 - x) * y + x * z)
probs.putScalar(k.toLong(), (1.0 - x) * z + x * y)
val x = probs[i]
val y = probs[j]
val z = probs[k]
val xFlip = 1f - x
probs[j] = xFlip * y + x * z
probs[k] = xFlip * z + x * y
}
is CCNot -> {
val x = probs.getDouble(i)
val y = probs.getDouble(j)
val z = probs.getDouble(k)
val probBoth0 = (1.0 - x) * (1.0 - y)
probs.putScalar(k.toLong(), probBoth0 * z + (1.0 - probBoth0) * (1.0 - z))
val x = probs[i]
val y = probs[j]
val z = probs[k]
val probBoth0 = (1f - x) * (1f - y)
probs[k] = probBoth0 * z + (1f - probBoth0) * (1f - z)
}
is Gen1Bit -> {
val x = probs.getDouble(i)
probs.putScalar(i.toLong(), x * (1.0 - q) * x + (1.0 - x) * (p + (1.0 - p) * x))
val x = probs[i]
probs[i] = x * (1f - q) * x + (1f - x) * (p + (1f - p) * x)
}
}
}
Expand All @@ -48,11 +57,12 @@ class Prob0Init(N: Int) : ProbFinder(N) {
override fun printResult() {
val probs = eval(getZeroVec())
allStates(N).forEach { endState ->
var prob = 1.0
var prob = 1f
endState.forEach { i ->
prob *= if (i > 0) probs.getDouble(i) else (1.0 - probs.getDouble(i))
val x = probs[i]
prob *= if (i > 0) x else 1f - x
}
println("Pr[%s] = %.9f".format(endState.joinToString(","), prob))
println("Pr[%s] = %.10f".format(endState.joinToString(","), prob))
}
}
}
92 changes: 49 additions & 43 deletions src/main/kotlin/operator/ProbAllInit.kt
Original file line number Diff line number Diff line change
@@ -1,69 +1,75 @@
package operator

import allStates
import org.nd4j.linalg.api.buffer.DataType
import org.nd4j.linalg.api.ndarray.INDArray
import org.nd4j.linalg.factory.Nd4j
import org.nd4j.linalg.string.NDArrayStrings
import org.ejml.data.FMatrixRMaj
import org.ejml.dense.row.CommonOps_FDRM
import org.ejml.kotlin.minus
import org.ejml.kotlin.plus
import org.ejml.kotlin.plusAssign
import org.ejml.kotlin.times
import util.elemMult
import util.getColumn
import util.putColumn
import util.scale
import kotlin.math.pow

/**
* Created by DEDZTBH on 2020/09/15.
* Project CMU_Coin-flipping_Experience
*/

fun allStatesFloat(n: Int) =
Array(2.0.pow(n).toInt()) {
FloatArray(n) { i -> ((it shr i) and 1).toFloat() }.apply { reverse() }
}

class ProbAllInit(N: Int) : ProbFinder(N) {
fun eval(probs: INDArray): INDArray {
fun eval(probs: FMatrixRMaj): FMatrixRMaj {
val broadcastVec =
FMatrixRMaj(probs.numRows,
1,
true,
*FloatArray(probs.numRows) { 1f })
operations.forEach {
it.apply {
when (this) {
is Matrix -> {
probs.muliRowVector(opVec)
probs.addiRowVector(opBias)
is MatrixOp -> {
CommonOps_FDRM.elementMult(probs, broadcastVec * opVec)
probs += broadcastVec * opBias
}
is CNot -> {
val i = i.toLong()
val j = j.toLong()
val x = probs.getColumn(i)
val y = probs.getColumn(j)
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)
probs.putColumn(j, (x elemMult y scale -2f) + x + y)
}
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)
val x = probs getColumn i
val y = probs getColumn j
val z = probs getColumn k
val xy = x elemMult y
val xz = x elemMult z
//(1.0 - x) * y + x * z
probs.putColumn(this.j, y.sub(xy).add(xz))
probs.putColumn(j, y - xy + xz)
//(1.0 - x) * z + x * y
probs.putColumn(this.k, z.sub(xz).add(xy))
probs.putColumn(k, z - xz + 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)
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)
val probBoth0 = (x elemMult y) - x - y + 1f
//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))
probs.putColumn(k, (probBoth0 elemMult z scale 2f) - probBoth0 - z + 1f)
}
is Gen1Bit -> {
val i = i.toLong()
val x = probs.getColumn(i)
val xx = x.mul(x)
val p_comp = 1.0 - p
val x = probs getColumn i
val xx = x elemMult x
val pComp = 1f - p
//x * (1.0 - q) * x + (1.0 - x) * (p + (1.0 - p) * x)
//= xx(1-q) + p + (1-p)x - xp - xx(1-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))
i, (xx scale 1f - q) + p + (x scale pComp) - (x scale p) - (xx scale pComp)
)
}
}
Expand All @@ -75,8 +81,8 @@ class ProbAllInit(N: Int) : ProbFinder(N) {
override fun printResult() {
val probs = eval(
// a 2^n by n matrix
Nd4j.create(allStates(N)).castTo(DataType.DOUBLE)
FMatrixRMaj(allStatesFloat(N))
)
println(probs.toString(NDArrayStrings(Long.MAX_VALUE, 9)))
probs.print()
}
}
37 changes: 17 additions & 20 deletions src/main/kotlin/operator/ProbFinder.kt
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
package operator

import org.nd4j.linalg.api.buffer.DataType
import org.nd4j.linalg.api.ndarray.INDArray
import org.nd4j.linalg.factory.Nd4j
import readDouble
import readInt
import org.ejml.data.FMatrixRMaj
import util.readFloat
import util.readInt

sealed class Operation
data class Matrix(val opVec: INDArray, val opBias: INDArray) : Operation()
data class MatrixOp(val opVec: FMatrixRMaj, val opBias: FMatrixRMaj) : Operation()
data class CNot(val i: Int, val j: Int) : Operation()
data class CSwap(val i: Int, val j: Int, val k: Int) : Operation()
data class CCNot(val i: Int, val j: Int, val k: Int) : Operation()
data class Gen1Bit(val i: Int, val p: Double, val q: Double) : Operation()
data class Gen1Bit(val i: Int, val p: Float, val q: Float) : Operation()

/**
* Created by DEDZTBH on 2020/09/15.
* Project CMU_Coin-flipping_Experience
*/
abstract class ProbFinder(val N: Int) : Operator {
fun getOneVec(): INDArray = Nd4j.ones(1, N).castTo(DataType.DOUBLE)
fun getZeroVec(): INDArray = Nd4j.zeros(1, N).castTo(DataType.DOUBLE)
fun getOneVec(): FMatrixRMaj = FMatrixRMaj(arrayOf(FloatArray(N) { 1f }))
fun getZeroVec(): FMatrixRMaj = FMatrixRMaj(1, N)
fun saveMatrix() {
if (matrixDirty) {
operations.add(Matrix(opVec, opBias))
operations.add(MatrixOp(opVec, opBias))
opVec = getOneVec()
opBias = getZeroVec()
matrixDirty = false
Expand All @@ -37,16 +35,15 @@ abstract class ProbFinder(val N: Int) : Operator {

override fun runCmd(cmd: String): Int {
val i = readInt()
val il = i.toLong()
when (cmd) {
"Flip" -> {
opVec.putScalar(il, 0.0)
opBias.putScalar(il, 0.5)
opVec[i] = 0f
opBias[i] = 0.5f
matrixDirty = true
}
"Not" -> {
opVec.putScalar(il, -opVec.getDouble(il))
opBias.putScalar(il, 1.0 - opBias.getDouble(il))
opVec[i] *= -1f
opBias[i] = 1f - opBias[i]
matrixDirty = true
}
"CNot" -> { // cannot represent in matrix op
Expand All @@ -67,14 +64,14 @@ abstract class ProbFinder(val N: Int) : Operator {
operations.add(CCNot(i, j, k))
}
"GenFlip" -> {
val j = readDouble()
opVec.putScalar(il, 0.0)
opBias.putScalar(il, j)
val j = readFloat()
opVec[i] = 0f
opBias[i] = j
matrixDirty = true
}
"Gen1Bit" -> { // cannot represent in matrix op
val p = readDouble()
val q = readDouble()
val p = readFloat()
val q = readFloat()
saveMatrix()
operations.add(Gen1Bit(i, p, q))
}
Expand Down
10 changes: 5 additions & 5 deletions src/main/kotlin/operator/Tester.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package operator

import readDouble
import readInt
import util.readFloat
import util.readInt
import kotlin.random.Random

/**
Expand Down Expand Up @@ -32,10 +32,10 @@ class Tester(N: Int) : Operator {
val k = readInt()
if (coins[i] or coins[j] != 0) coins flip k
}
"GenFlip" -> coins[i] = if (Random.nextDouble() < readDouble()) 1 else 0
"GenFlip" -> coins[i] = if (Random.nextDouble() < readFloat()) 1 else 0
"Gen1Bit" -> {
val p = readDouble()
val q = readDouble()
val p = readFloat()
val q = readFloat()
if (coins[i] == 0) {
if (Random.nextDouble() < p) coins[i] = 1
} else
Expand Down
10 changes: 3 additions & 7 deletions src/main/kotlin/util.kt → src/main/kotlin/util/io.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package util

import java.io.BufferedReader
import java.util.*
import kotlin.math.pow

/**
* Created by DEDZTBH on 2020/09/15.
Expand All @@ -16,11 +17,6 @@ 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() }
}
fun readFloat() = read().toFloat()

lateinit var reader: BufferedReader
Loading

0 comments on commit 202d997

Please sign in to comment.