package scientific.stats.mcmc
import std.math.*
import std.collection.*
import std.io.*
// record Pair<T, U> {
// let x: T
// let y: U
// public init(a: T, b: U) {
// x = a
// y = b
// }
// public func first(): T { return x }
// public func second(): U { return y }
// }
// @Differentiable
// func f(x: Float64, y: Float64) : Float64 {
// return x * x * y
// }
// @Adjoint [primal: f]
// func g(x: Float64, y: Float64): (Float64)*((Float64) -> Float64 * Float64) {
// let x_squre = x * x
// return (
// x_squre * x,
// { dy: Float64 =>
// return (dy * x_squre * 2.0, dy * 2.0)
// }
// )
// }
// @Differentiable [except: [x]]
// public func normalPDF(x: Float64, mean: Float64, std: Float64): Float64 {
// let temp = 1.0 / sqrt(2.0 * Float64.getPI()) * exp(-pow(x - mean, 2.0) / (2.0 * pow(std, 2.0)))
// return temp
// }
// @Adjoint [primal: normalPDF]
// public func normalPDFAcc(x: Float64, mean: Float64, std: Float64): (Float64)*((Float64) -> Float64 * Float64) {
// let temp = 1.0 / sqrt(2.0 * Float64.getPI()) * exp(-pow(x - mean, 2.0) / (2.0 * pow(std, 2.0)))
// return (
// temp,
// { dy: Float64 =>
// return (temp * (-(mean - x) / pow(std, 2.0)), temp * (- 1.0 / std + pow(x - mean, 2.0) / pow(std, 3.0)))
// }
// )
// }
// class McmcDist {
// var params: Tensor<Float64> = Tensor<Float64>([0.0, 1.0])
// let params: Array<Float64> = Array<Float64>([0.2, 1.0])
// open func density(x: Float64): Float64 {
// return 0.0
// }
// open func density(x: Float64, params: Tensor<Float64>): Float64 {
// return 0.0
// }
// }
// func main() {
// public func testMCMC() {
// // let product_grad = grad(normalPDF, (0.0, 3.0, 2.0))
// // print(product_grad[0].toString() + "\n")
// // print(product_grad[1].toString() + "\n")
// // let product_grad = grad(f, (2.0, 3.0))
// // print(product_grad[0].toString() + "\n")
// // print(product_grad[1].toString() + "\n")
// // var a: Pair<String, Int64> = Pair<String, Int64>("hello", 0)
// // println(a.first())
// // println(a.second())
// // let p: McmcDist = McmcDist()
// // let param1: Array<Int64> = [1, 2]
// // print("${param1[0]}")
// //test io
// let pathname: String = "./australian.txt"
// var fs: FileStream = FileStream(pathname)
// if (fs.openFile()) {
// var toWrite: Array<UInt8> = Array<UInt8>(80, { i => 0 })
// var res = fs.write(toWrite)
// fs.flush()
// println(res.toString())
// fs.close()
// println(fs.isClosed().toString())
// }
// if (fs.openFile()) {
// var toRead: Array<UInt8> = Array<UInt8>(25, { i => 0 })
// fs.read(toRead)
// fs.flush()
// var n = fs.seek(6, SeekOrigin.BeginPos)
// println(n.toString())
// fs.close()
// println(toRead.toString())
// println(fs.isClosed().toString())
// }
// fs.close()
// return 0
// }