package scientific.linear.benchmarks

import std.time.*

import scientific.utils.assertEqual
import scientific.stats.random.Random
import scientific.stats.normal.randn
import scientific.linear.*

public func multPerformance(dim: Int64, seed: Int64): Float64 {
    let m = Random(UInt32(seed))
    print("Testing multiplication with dimension ${dim} and seed ${seed}:\n")

    var total_ms = 0.0
    let A: Matrix<Float64> = randn(m, dim, dim, 0.0, 1.0)
    let B: Matrix<Float64> = randn(m, dim, dim, 0.0, 1.0)

    let start = DateTime.now()
    let X = Float64.matprod(A, B)
    let end = DateTime.now()
    let exectime = end - start
    total_ms += Float64(exectime.toMicroseconds()) / 1000.0
    print("Time taken: ${total_ms} ms\n")
    return total_ms
}

public func solvePerformance(dim: Int64, seed: Int64): Float64 {
    let m = Random(UInt32(seed))
    print("Testing solve with dimension ${dim} and seed ${seed}:\n")

    var total_ms = 0.0
    let A = randn(m, dim, dim, 0.0, 1.0)
    let B = randn(m, dim, 0.0, 1.0)

    let start = DateTime.now()
    let X = solve(A, B)
    let end = DateTime.now()
    let exectime = end - start
    total_ms += Float64(exectime.toMicroseconds()) / 1000.0
    print("Time taken: ${total_ms} ms\n")
    return total_ms
}


public func invPerformance(dim: Int64, seed: Int64): Float64 {
    let m = Random(UInt32(seed))

    print("Testing inv with dimension ${dim} and seed ${seed}:\n")

    var total_ms = 0.0
    let A = randn(m, dim, dim, 0.0, 1.0)
    let start = DateTime.now()
    var invA = inv(A)
    let end = DateTime.now()
    let exectime = end - start
    total_ms += Float64(exectime.toMicroseconds()) / 1000.0
    print("Time taken: ${total_ms} ms\n")
    return total_ms
}