// File: sebastienmeyer2[P]mst-clustering/src/compare_clustering.cpp
// Function: compare_clustering(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int)
void compare_clustering(std::string file_to_read, int k)
{
    /*!
     * @brief From a file given as entry and an integer k for the number of 
     * clusters to draw, establishes a comparison between kmeans and MST clustering
     * 
     * @param file_to_read Path to the data
     * @param k Number of clusters to draw
     * 
     */

	// get points from datafile

	std::ifstream is(file_to_read);
	assert(is.is_open());

	std::string header_line;
	std::getline(is, header_line);

	const int d = nb_columns(header_line) - 1;
    Point::d = d;

    std::vector<Point*> points = Point::read_points_from_file(file_to_read, d);
    int n = points.size();

    // run MST clustering 

    std::chrono::steady_clock::time_point graph_creation = std::chrono::steady_clock::now();

    std::cout << "\nCreating graph...";
    Graph* g = new Graph(points);
    std::cout << "[OK]" << std::endl;

    std::chrono::steady_clock::time_point kruskal_algo = std::chrono::steady_clock::now();

    KruskalAlgorithm kruskal = KruskalAlgorithm(g);
    kruskal.compute_mst();

    std::chrono::steady_clock::time_point kruskal_clustering = std::chrono::steady_clock::now();

    std::unordered_map<Node*, Node*> clusters = kruskal.compute_clustering(k);

    std::chrono::steady_clock::time_point mst_end = std::chrono::steady_clock::now();

    // run kmeans 

    std::chrono::steady_clock::time_point cloud_creation = std::chrono::steady_clock::now();

    std::cout << "\nCreating cloud...";

    Cloud cloud = Cloud(d, n, k);

    int label = 0;
    for (int i = 0; i < n; i ++) {
        cloud.add_point(*points[i], label);
        label = (label+1) % k;
    }

    std::cout << "[OK]" << std::endl;

    std::chrono::steady_clock::time_point kmeans_algo = std::chrono::steady_clock::now();

    cloud.kmeans();

    std::chrono::steady_clock::time_point kmeans_end = std::chrono::steady_clock::now();

    // comparison

    std::cout << "\nTotal time spent by MST clustering including graph creation: ";
    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(mst_end - graph_creation).count() << " µs" << std::endl;

    std::cout << "Total time spent by MST clustering: ";
    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(mst_end - kruskal_algo).count() << " µs" << std::endl;

    double mst_variance = intracluster_variance(clusters);
    std::cout << "Intracluster variance in MST: ";
    std::cout << mst_variance << std::endl;

    double mst_silhouette = silhouette(clusters);
    std::cout << "Silhouette in MST: ";
    std::cout << mst_silhouette << std::endl;

    std::cout << "\nTotal time spent by kmeans including cloud creation: ";
    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(kmeans_end - cloud_creation).count() << " µs" << std::endl;

    std::cout << "Total time spent by kmeans: ";
    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(kmeans_end - kmeans_algo).count() << " µs" << std::endl;

    double kmeans_variance = cloud.intracluster_variance();
    std::cout << "Intracluster variance in kmeans: ";
    std::cout << kmeans_variance << std::endl;

    double kmeans_silhouette = cloud.silhouette();
    std::cout << "Silhouette in kmeans: ";
    std::cout << kmeans_silhouette << std::endl;

    return;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x650, %rsp            # imm = 0x650
movl %esi, %eax
movq %rdi, %rsi
movq %rsi, -0x540(%rbp)
movq %rsi, -0x8(%rbp)
movl %eax, -0xc(%rbp)
leaq -0x218(%rbp), %rdi
movq %rdi, -0x538(%rbp)
movl $0x8, %edx
callq 0xac80
movq -0x538(%rbp), %rdi
callq 0xac60
movb %al, -0x529(%rbp)
jmp 0x33f7a
movb -0x529(%rbp), %al
testb $0x1, %al
jne 0x33f86
jmp 0x33f88
jmp 0x33fbe
leaq 0x3be5(%rip), %rdi      # 0x37b74
leaq 0x3beb(%rip), %rsi      # 0x37b81
movl $0x1f, %edx
leaq 0x3bfa(%rip), %rcx      # 0x37b9c
callq 0xa4a0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x3493e
leaq -0x248(%rbp), %rdi
movq %rdi, -0x548(%rbp)
callq 0xaad0
movq -0x548(%rbp), %rsi
leaq -0x218(%rbp), %rdi
callq 0xa120
jmp 0x33fe6
leaq -0x248(%rbp), %rdi
callq 0x33eb0
movl %eax, -0x54c(%rbp)
jmp 0x33ffa
movq -0x540(%rbp), %rsi
movl -0x54c(%rbp), %eax
decl %eax
movl %eax, -0x24c(%rbp)
movl -0x24c(%rbp), %ecx
leaq 0x1c7dc(%rip), %rax     # 0x507f8
movl %ecx, (%rax)
leaq -0x288(%rbp), %rdi
callq 0xa2a0
jmp 0x3402c
movl -0x24c(%rbp), %edx
leaq -0x268(%rbp), %rdi
leaq -0x288(%rbp), %rsi
callq 0xb6f0
jmp 0x34047
leaq -0x288(%rbp), %rdi
callq 0xa470
leaq -0x268(%rbp), %rdi
callq 0xc120
movl %eax, -0x28c(%rbp)
callq 0xaa70
movq %rax, -0x298(%rbp)
movq 0x1bf38(%rip), %rdi     # 0x4ffb0
leaq 0x3b47(%rip), %rsi      # 0x37bc6
callq 0xa780
jmp 0x34086
movl $0xe8, %edi
callq 0xa790
movq %rax, -0x558(%rbp)
jmp 0x34099
movb $0x1, -0x2b9(%rbp)
leaq -0x2b8(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0x356e0
jmp 0x340b5
movq -0x558(%rbp), %rdi
leaq -0x2b8(%rbp), %rsi
callq 0xd090
jmp 0x340ca
movb $0x0, -0x2b9(%rbp)
leaq -0x2b8(%rbp), %rdi
callq 0xba30
movq -0x558(%rbp), %rax
movq %rax, -0x2a0(%rbp)
movq 0x1bebe(%rip), %rdi     # 0x4ffb0
leaq 0x37af(%rip), %rsi      # 0x378a8
callq 0xa780
movq %rax, -0x560(%rbp)
jmp 0x34107
movq -0x560(%rbp), %rdi
movq 0x1be73(%rip), %rsi     # 0x4ff88
callq 0xa7e0
jmp 0x3411c
callq 0xaa70
movq %rax, -0x2c8(%rbp)
movq -0x2a0(%rbp), %rsi
leaq -0x3d0(%rbp), %rdi
callq 0x2e540
jmp 0x3413d
leaq -0x3d0(%rbp), %rdi
callq 0x2e580
jmp 0x3414b
callq 0xaa70
movq %rax, -0x3d8(%rbp)
movl -0xc(%rbp), %edx
leaq -0x410(%rbp), %rdi
leaq -0x3d0(%rbp), %rsi
callq 0x265e0
jmp 0x3416f
callq 0xaa70
movq %rax, -0x418(%rbp)
callq 0xaa70
movq %rax, -0x420(%rbp)
movq 0x1be22(%rip), %rdi     # 0x4ffb0
leaq 0x3a44(%rip), %rsi      # 0x37bd9
callq 0xa780
jmp 0x3419c
movl -0x24c(%rbp), %esi
movl -0x28c(%rbp), %edx
movl -0xc(%rbp), %ecx
leaq -0x440(%rbp), %rdi
callq 0x32550
jmp 0x341b9
movl $0x0, -0x444(%rbp)
movl $0x0, -0x448(%rbp)
movl -0x448(%rbp), %eax
cmpl -0x28c(%rbp), %eax
jge 0x34316
movslq -0x448(%rbp), %rsi
leaq -0x268(%rbp), %rdi
callq 0xde90
movq (%rax), %rsi
movl -0x444(%rbp), %edx
leaq -0x440(%rbp), %rdi
callq 0x328b0
jmp 0x34209
movl -0x444(%rbp), %eax
addl $0x1, %eax
cltd
idivl -0xc(%rbp)
movl %edx, -0x444(%rbp)
movl -0x448(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x448(%rbp)
jmp 0x341cd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x34932
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x288(%rbp), %rdi
callq 0xa470
jmp 0x34932
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x34926
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x342b0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x2b8(%rbp), %rdi
callq 0xba30
testb $0x1, -0x2b9(%rbp)
jne 0x342bb
jmp 0x342cc
movq -0x558(%rbp), %rdi
movl $0xe8, %esi
callq 0xa7b0
jmp 0x34926
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x3491a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x3490e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x34902
movq 0x1bc93(%rip), %rdi     # 0x4ffb0
leaq 0x3584(%rip), %rsi      # 0x378a8
callq 0xa780
movq %rax, -0x568(%rbp)
jmp 0x34332
movq -0x568(%rbp), %rdi
movq 0x1bc48(%rip), %rsi     # 0x4ff88
callq 0xa7e0
jmp 0x34347
callq 0xaa70
movq %rax, -0x450(%rbp)
leaq -0x440(%rbp), %rdi
callq 0x33030
jmp 0x34361
callq 0xaa70
movq %rax, -0x458(%rbp)
movq 0x1bc3c(%rip), %rdi     # 0x4ffb0
leaq 0x3871(%rip), %rsi      # 0x37bec
callq 0xa780
jmp 0x34382
leaq -0x418(%rbp), %rdi
leaq -0x298(%rbp), %rsi
callq 0x2b6a0
movq %rax, -0x570(%rbp)
jmp 0x3439e
movq -0x570(%rbp), %rax
movq %rax, -0x468(%rbp)
leaq -0x468(%rbp), %rdi
callq 0x2b670
movq %rax, -0x578(%rbp)
jmp 0x343c1
movq -0x578(%rbp), %rax
movq %rax, -0x460(%rbp)
leaq -0x460(%rbp), %rdi
callq 0x2b6f0
movq %rax, -0x580(%rbp)
jmp 0x343e4
movq -0x580(%rbp), %rsi
movq 0x1bbbe(%rip), %rdi     # 0x4ffb0
callq 0xae50
movq %rax, -0x588(%rbp)
jmp 0x34400
movq -0x588(%rbp), %rdi
leaq 0x34d7(%rip), %rsi      # 0x378e5
callq 0xa780
movq %rax, -0x590(%rbp)
jmp 0x3441c
movq -0x590(%rbp), %rdi
movq 0x1bb5e(%rip), %rsi     # 0x4ff88
callq 0xa7e0
jmp 0x34431
movq 0x1bb78(%rip), %rdi     # 0x4ffb0
leaq 0x37ec(%rip), %rsi      # 0x37c2b
callq 0xa780
jmp 0x34446
leaq -0x418(%rbp), %rdi
leaq -0x2c8(%rbp), %rsi
callq 0x2b6a0
movq %rax, -0x598(%rbp)
jmp 0x34462
movq -0x598(%rbp), %rax
movq %rax, -0x478(%rbp)
leaq -0x478(%rbp), %rdi
callq 0x2b670
movq %rax, -0x5a0(%rbp)
jmp 0x34485
movq -0x5a0(%rbp), %rax
movq %rax, -0x470(%rbp)
leaq -0x470(%rbp), %rdi
callq 0x2b6f0
movq %rax, -0x5a8(%rbp)
jmp 0x344a8
movq -0x5a8(%rbp), %rsi
movq 0x1bafa(%rip), %rdi     # 0x4ffb0
callq 0xae50
movq %rax, -0x5b0(%rbp)
jmp 0x344c4
movq -0x5b0(%rbp), %rdi
leaq 0x3413(%rip), %rsi      # 0x378e5
callq 0xa780
movq %rax, -0x5b8(%rbp)
jmp 0x344e0
movq -0x5b8(%rbp), %rdi
movq 0x1ba9a(%rip), %rsi     # 0x4ff88
callq 0xa7e0
jmp 0x344f5
leaq -0x4b8(%rbp), %rdi
leaq -0x410(%rbp), %rsi
callq 0x357d0
jmp 0x3450a
leaq -0x4b8(%rbp), %rdi
callq 0x231d0
movsd %xmm0, -0x5c0(%rbp)
jmp 0x34520
leaq -0x4b8(%rbp), %rdi
callq 0x1be30
movsd -0x5c0(%rbp), %xmm0
movsd %xmm0, -0x480(%rbp)
movq 0x1ba6d(%rip), %rdi     # 0x4ffb0
leaq 0x3706(%rip), %rsi      # 0x37c50
callq 0xa780
jmp 0x34551
movsd -0x480(%rbp), %xmm0
movq 0x1ba50(%rip), %rdi     # 0x4ffb0
callq 0xaee0
movq %rax, -0x5c8(%rbp)
jmp 0x3456e
movq -0x5c8(%rbp), %rdi
movq 0x1ba0c(%rip), %rsi     # 0x4ff88
callq 0xa7e0
jmp 0x34583
leaq -0x4f8(%rbp), %rdi
leaq -0x410(%rbp), %rsi
callq 0x357d0
jmp 0x34598
leaq -0x4f8(%rbp), %rdi
callq 0x238f0
movsd %xmm0, -0x5d0(%rbp)
jmp 0x345ae
leaq -0x4f8(%rbp), %rdi
callq 0x1be30
movsd -0x5d0(%rbp), %xmm0
movsd %xmm0, -0x4c0(%rbp)
movq 0x1b9df(%rip), %rdi     # 0x4ffb0
leaq 0x3697(%rip), %rsi      # 0x37c6f
callq 0xa780
jmp 0x345df
movsd -0x4c0(%rbp), %xmm0
movq 0x1b9c2(%rip), %rdi     # 0x4ffb0
callq 0xaee0
movq %rax, -0x5d8(%rbp)
jmp 0x345fc
movq -0x5d8(%rbp), %rdi
movq 0x1b97e(%rip), %rsi     # 0x4ff88
callq 0xa7e0
jmp 0x34611
movq 0x1b998(%rip), %rdi     # 0x4ffb0
leaq 0x3664(%rip), %rsi      # 0x37c83
callq 0xa780
jmp 0x34626
leaq -0x458(%rbp), %rdi
leaq -0x420(%rbp), %rsi
callq 0x2b6a0
movq %rax, -0x5e0(%rbp)
jmp 0x34642
movq -0x5e0(%rbp), %rax
movq %rax, -0x508(%rbp)
leaq -0x508(%rbp), %rdi
callq 0x2b670
movq %rax, -0x5e8(%rbp)
jmp 0x34665
movq -0x5e8(%rbp), %rax
movq %rax, -0x500(%rbp)
leaq -0x500(%rbp), %rdi
callq 0x2b6f0
movq %rax, -0x5f0(%rbp)
jmp 0x34688
movq -0x5f0(%rbp), %rsi
movq 0x1b91a(%rip), %rdi     # 0x4ffb0
callq 0xae50
movq %rax, -0x5f8(%rbp)
jmp 0x346a4
movq -0x5f8(%rbp), %rdi
leaq 0x3233(%rip), %rsi      # 0x378e5
callq 0xa780
movq %rax, -0x600(%rbp)
jmp 0x346c0
movq -0x600(%rbp), %rdi
movq 0x1b8ba(%rip), %rsi     # 0x4ff88
callq 0xa7e0
jmp 0x346d5
movq 0x1b8d4(%rip), %rdi     # 0x4ffb0
leaq 0x35d7(%rip), %rsi      # 0x37cba
callq 0xa780
jmp 0x346ea
leaq -0x458(%rbp), %rdi
leaq -0x450(%rbp), %rsi
callq 0x2b6a0
movq %rax, -0x608(%rbp)
jmp 0x34706
movq -0x608(%rbp), %rax
movq %rax, -0x518(%rbp)
leaq -0x518(%rbp), %rdi
callq 0x2b670
movq %rax, -0x610(%rbp)
jmp 0x34729
movq -0x610(%rbp), %rax
movq %rax, -0x510(%rbp)
leaq -0x510(%rbp), %rdi
callq 0x2b6f0
movq %rax, -0x618(%rbp)
jmp 0x3474c
movq -0x618(%rbp), %rsi
movq 0x1b856(%rip), %rdi     # 0x4ffb0
callq 0xae50
movq %rax, -0x620(%rbp)
jmp 0x34768
movq -0x620(%rbp), %rdi
leaq 0x316f(%rip), %rsi      # 0x378e5
callq 0xa780
movq %rax, -0x628(%rbp)
jmp 0x34784
movq -0x628(%rbp), %rdi
movq 0x1b7f6(%rip), %rsi     # 0x4ff88
callq 0xa7e0
jmp 0x34799
leaq -0x440(%rbp), %rdi
callq 0x32aa0
movsd %xmm0, -0x630(%rbp)
jmp 0x347af
movsd -0x630(%rbp), %xmm0
movsd %xmm0, -0x520(%rbp)
movq 0x1b7ea(%rip), %rdi     # 0x4ffb0
leaq 0x350a(%rip), %rsi      # 0x37cd7
callq 0xa780
jmp 0x347d4
movsd -0x520(%rbp), %xmm0
movq 0x1b7cd(%rip), %rdi     # 0x4ffb0
callq 0xaee0
movq %rax, -0x638(%rbp)
jmp 0x347f1
movq -0x638(%rbp), %rdi
movq 0x1b789(%rip), %rsi     # 0x4ff88
callq 0xa7e0
jmp 0x34806
leaq -0x440(%rbp), %rdi
callq 0x33a40
movsd %xmm0, -0x640(%rbp)
jmp 0x3481c
movsd -0x640(%rbp), %xmm0
movsd %xmm0, -0x528(%rbp)
movq 0x1b77d(%rip), %rdi     # 0x4ffb0
leaq 0x34bf(%rip), %rsi      # 0x37cf9
callq 0xa780
jmp 0x34841
movsd -0x528(%rbp), %xmm0
movq 0x1b760(%rip), %rdi     # 0x4ffb0
callq 0xaee0
movq %rax, -0x648(%rbp)
jmp 0x3485e
movq -0x648(%rbp), %rdi
movq 0x1b71c(%rip), %rsi     # 0x4ff88
callq 0xa7e0
jmp 0x34873
leaq -0x440(%rbp), %rdi
callq 0x327b0
leaq -0x410(%rbp), %rdi
callq 0x1be30
leaq -0x3d0(%rbp), %rdi
callq 0x1b8a0
leaq -0x268(%rbp), %rdi
callq 0xba30
leaq -0x248(%rbp), %rdi
callq 0xa470
leaq -0x218(%rbp), %rdi
callq 0xa1b0
addq $0x650, %rsp            # imm = 0x650
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x4b8(%rbp), %rdi
callq 0x1be30
jmp 0x34902
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x4f8(%rbp), %rdi
callq 0x1be30
leaq -0x440(%rbp), %rdi
callq 0x327b0
leaq -0x410(%rbp), %rdi
callq 0x1be30
leaq -0x3d0(%rbp), %rdi
callq 0x1b8a0
leaq -0x268(%rbp), %rdi
callq 0xba30
leaq -0x248(%rbp), %rdi
callq 0xa470
leaq -0x218(%rbp), %rdi
callq 0xa1b0
movq -0x220(%rbp), %rdi
callq 0xade0
nopw %cs:(%rax,%rax)