// File: /workspace/github_cpp_makefile_star2_O2/Ripser[P]ripser/ripser.cpp
// Function: main
int main(int argc, char** argv) {
	const char* filename = nullptr;

	file_format format = DISTANCE_MATRIX;

	index_t dim_max = 1;
	value_t threshold = std::numeric_limits<value_t>::max();
	float ratio = 1;
	coefficient_t modulus = 2;

	for (index_t i = 1; i < argc; ++i) {
		const std::string arg(argv[i]);
		if (arg == "--help") {
			print_usage_and_exit(0);
		} else if (arg == "--dim") {
			std::string parameter = std::string(argv[++i]);
			size_t next_pos;
			dim_max = std::stol(parameter, &next_pos);
			if (next_pos != parameter.size()) print_usage_and_exit(-1);
		} else if (arg == "--threshold") {
			std::string parameter = std::string(argv[++i]);
			size_t next_pos;
			threshold = std::stof(parameter, &next_pos);
			if (next_pos != parameter.size()) print_usage_and_exit(-1);
		} else if (arg == "--ratio") {
			std::string parameter = std::string(argv[++i]);
			size_t next_pos;
			ratio = std::stof(parameter, &next_pos);
			if (next_pos != parameter.size()) print_usage_and_exit(-1);
		} else if (arg == "--format") {
			std::string parameter = std::string(argv[++i]);
			if (parameter.rfind("lower", 0) == 0)
				format = LOWER_DISTANCE_MATRIX;
			else if (parameter.rfind("upper", 0) == 0)
				format = UPPER_DISTANCE_MATRIX;
			else if (parameter.rfind("dist", 0) == 0)
				format = DISTANCE_MATRIX;
			else if (parameter.rfind("point", 0) == 0)
				format = POINT_CLOUD;
			else if (parameter == "dipha")
				format = DIPHA;
			else if (parameter == "sparse")
				format = SPARSE;
			else if (parameter == "binary")
				format = BINARY;
			else
				print_usage_and_exit(-1);
#ifdef USE_COEFFICIENTS
		} else if (arg == "--modulus") {
			std::string parameter = std::string(argv[++i]);
			size_t next_pos;
			modulus = std::stol(parameter, &next_pos);
			if (next_pos != parameter.size() || !is_prime(modulus)) print_usage_and_exit(-1);
#endif
		} else {
			if (filename) { print_usage_and_exit(-1); }
			filename = argv[i];
		}
	}

	std::ifstream file_stream(filename);
	if (filename && file_stream.fail()) {
		std::cerr << "couldn't open file " << filename << std::endl;
		exit(-1);
	}

	if (format == SPARSE) {
		sparse_distance_matrix dist =
		    read_sparse_distance_matrix(filename ? file_stream : std::cin);
		std::cout << "sparse distance matrix with " << dist.size() << " points and "
		          << dist.num_edges << "/" << (dist.size() * (dist.size() - 1)) / 2 << " entries"
		          << std::endl;

		ripser<sparse_distance_matrix>(std::move(dist), dim_max, threshold, ratio, modulus)
		    .compute_barcodes();
	} else if (format == POINT_CLOUD && threshold < std::numeric_limits<value_t>::max()) {
		sparse_distance_matrix dist(read_point_cloud(filename ? file_stream : std::cin), threshold);
		ripser<sparse_distance_matrix>(std::move(dist), dim_max, threshold, ratio, modulus)
				.compute_barcodes();
	} else {
		compressed_lower_distance_matrix dist =
		    read_file(filename ? file_stream : std::cin, format);

		value_t min = std::numeric_limits<value_t>::infinity(),
		        max = -std::numeric_limits<value_t>::infinity(), max_finite = max;
		int num_edges = 0;

		value_t enclosing_radius = std::numeric_limits<value_t>::infinity();
		if (threshold == std::numeric_limits<value_t>::max()) {
			for (size_t i = 0; i < dist.size(); ++i) {
				value_t r_i = -std::numeric_limits<value_t>::infinity();
				for (size_t j = 0; j < dist.size(); ++j) r_i = std::max(r_i, dist(i, j));
				enclosing_radius = std::min(enclosing_radius, r_i);
			}
		}

		for (auto d : dist.distances) {
			min = std::min(min, d);
			max = std::max(max, d);
			if (d != std::numeric_limits<value_t>::infinity()) max_finite = std::max(max_finite, d);
			if (d <= threshold) ++num_edges;
		}
		std::cout << "value range: [" << min << "," << max_finite << "]" << std::endl;

		if (threshold == std::numeric_limits<value_t>::max()) {
			std::cout << "distance matrix with " << dist.size()
			          << " points, using threshold at enclosing radius " << enclosing_radius
			          << std::endl;
			ripser<compressed_lower_distance_matrix>(std::move(dist), dim_max, enclosing_radius,
			                                         ratio, modulus)
			    .compute_barcodes();
		} else {
			std::cout << "sparse distance matrix with " << dist.size() << " points and "
			          << num_edges << "/" << (dist.size() * (dist.size() - 1)) / 2 << " entries"
			          << std::endl;

			ripser<sparse_distance_matrix>(sparse_distance_matrix(std::move(dist), threshold),
			                               dim_max, threshold, ratio, modulus)
			    .compute_barcodes();
		}
		exit(0);
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x338, %rsp            # imm = 0x338
movq %rsi, %r15
movslq %edi, %r14
pushq $0x2
popq %rax
movss 0x8cbc(%rip), %xmm0     # 0xc06c
movss %xmm0, 0xc(%rsp)
movss 0x8cb2(%rip), %xmm0     # 0xc070
movss %xmm0, 0x4(%rsp)
pushq $0x1
popq %rbx
movq $0x0, 0x10(%rsp)
leaq 0x130(%rsp), %r12
leaq 0x60(%rsp), %r13
leaq 0x20(%rsp), %rbp
pushq $-0x1
popq %rcx
movl %ecx, 0x8(%rsp)
movq %rax, 0x50(%rsp)
movq %rbx, 0x18(%rsp)
cmpq %r14, %rbx
jge 0x3629
movq (%r15,%rbx,8), %rsi
movq %r12, %rdi
movq %r13, %rdx
callq 0x20b0
movq %r12, %rdi
leaq 0x90c9(%rip), %rsi      # 0xc4de
callq 0x43a9
testb %al, %al
jne 0x380a
movq %r12, %rdi
leaq 0x90b9(%rip), %rsi      # 0xc4e5
callq 0x43a9
testb %al, %al
je 0x346d
movq 0x8(%r15,%rbx,8), %rsi
movq %r13, %rdi
movq %rbp, %rdx
callq 0x20b0
movq %r13, %rdi
movq %rbp, %rsi
pushq $0xa
popq %rdx
callq 0x43b6
movq %rax, 0x18(%rsp)
movq 0x20(%rsp), %rax
cmpq 0x68(%rsp), %rax
je 0x34f6
jmp 0x381b
movq %r12, %rdi
leaq 0x9074(%rip), %rsi      # 0xc4eb
callq 0x43a9
testb %al, %al
je 0x34b2
movq 0x8(%r15,%rbx,8), %rsi
movq %r13, %rdi
movq %rbp, %rdx
callq 0x20b0
movq %r13, %rdi
movq %rbp, %rsi
callq 0x43d2
movss %xmm0, 0x4(%rsp)
movq 0x20(%rsp), %rax
cmpq 0x68(%rsp), %rax
je 0x34f6
jmp 0x3823
movq %r12, %rdi
leaq 0x903b(%rip), %rsi      # 0xc4f7
callq 0x43a9
testb %al, %al
je 0x3511
movq 0x8(%r15,%rbx,8), %rsi
movq %r13, %rdi
movq %rbp, %rdx
callq 0x20b0
movq %r13, %rdi
movq %rbp, %rsi
callq 0x43d2
movss %xmm0, 0xc(%rsp)
movq 0x20(%rsp), %rax
cmpq 0x68(%rsp), %rax
jne 0x382b
incq %rbx
movq %r13, %rdi
callq 0x2388
movq %r12, %rdi
callq 0x2388
incq %rbx
jmp 0x33f3
movq %r12, %rdi
leaq 0x8fe4(%rip), %rsi      # 0xc4ff
callq 0x43a9
testb %al, %al
je 0x360f
movq 0x8(%r15,%rbx,8), %rsi
movq %r13, %rdi
movq %rbp, %rdx
callq 0x20b0
xorl %ebp, %ebp
movq %r13, %rdi
leaq 0x8fc4(%rip), %rsi      # 0xc508
xorl %edx, %edx
callq 0x22d0
testq %rax, %rax
je 0x35f5
movq %r13, %rdi
leaq 0x8fb0(%rip), %rsi      # 0xc50e
xorl %edx, %edx
callq 0x22d0
pushq $0x1
popq %rcx
movl %ecx, %ebp
testq %rax, %rax
je 0x35f5
movq %r13, %rdi
leaq 0x8f97(%rip), %rsi      # 0xc514
xorl %edx, %edx
callq 0x22d0
pushq $0x2
popq %rcx
movl %ecx, %ebp
testq %rax, %rax
je 0x35f5
movq %r13, %rdi
leaq 0x8f81(%rip), %rsi      # 0xc519
xorl %edx, %edx
callq 0x22d0
pushq $0x3
popq %rcx
movl %ecx, %ebp
testq %rax, %rax
je 0x35f5
movq %r13, %rdi
leaq 0x8f6c(%rip), %rsi      # 0xc51f
callq 0x43a9
pushq $0x4
popq %rcx
movl %ecx, %ebp
testb %al, %al
jne 0x35f5
movq %r13, %rdi
leaq 0x8f5a(%rip), %rsi      # 0xc525
callq 0x43a9
pushq $0x5
popq %rcx
movl %ecx, %ebp
testb %al, %al
jne 0x35f5
movq %r13, %rdi
leaq 0x8f49(%rip), %rsi      # 0xc52c
callq 0x43a9
pushq $0x6
popq %rcx
movl %ecx, %ebp
testb %al, %al
je 0x3a88
movq %rbp, 0x50(%rsp)
incq %rbx
movq %r13, %rdi
callq 0x2388
leaq 0x20(%rsp), %rbp
jmp 0x3501
cmpq $0x0, 0x10(%rsp)
jne 0x3812
movq (%r15,%rbx,8), %rax
movq %rax, 0x10(%rsp)
jmp 0x3501
leaq 0x130(%rsp), %r14
pushq $0x8
popq %rdx
movq %r14, %rdi
movq 0x10(%rsp), %rbx
movq %rbx, %rsi
callq 0x2340
testq %rbx, %rbx
je 0x3663
movq 0x130(%rsp), %rax
movq -0x18(%rax), %rax
testb $0x5, 0x150(%rsp,%rax)
jne 0x3841
movq 0x50(%rsp), %rax
cmpl $0x3, %eax
je 0x3756
cmpl $0x5, %eax
jne 0x3833
testq %rbx, %rbx
jne 0x3686
movq 0xf952(%rip), %r14      # 0x12fd8
leaq 0x20(%rsp), %rdi
movq %r14, %rsi
callq 0x2b15
movq 0xf91e(%rip), %rdi      # 0x12fb8
leaq 0x8ea6(%rip), %rsi      # 0xc547
callq 0x21f0
movq %rax, %rdi
movq 0x28(%rsp), %rax
subq 0x20(%rsp), %rax
pushq $0x18
popq %rbx
cqto
idivq %rbx
movq %rax, %rsi
callq 0x2170
leaq 0x8e9a(%rip), %rsi      # 0xc564
movq %rax, %rdi
callq 0x21f0
movq 0x38(%rsp), %rsi
movq %rax, %rdi
callq 0x21e0
leaq 0x8e8b(%rip), %rsi      # 0xc571
movq %rax, %rdi
callq 0x21f0
movq %rax, %rdi
movq 0x28(%rsp), %rax
subq 0x20(%rsp), %rax
cqto
idivq %rbx
leaq -0x1(%rax), %rsi
imulq %rax, %rsi
shrq %rsi
callq 0x2170
leaq 0x8e5c(%rip), %rsi      # 0xc573
movq %rax, %rdi
callq 0x21f0
movq %rax, %rdi
callq 0x20e0
leaq 0x60(%rsp), %rdi
leaq 0x20(%rsp), %rsi
pushq $0x2
popq %rcx
movq 0x18(%rsp), %rdx
movss 0x4(%rsp), %xmm0
movss 0xc(%rsp), %xmm1
callq 0x43ec
leaq 0x60(%rsp), %rdi
callq 0x44a8
jmp 0x37d5
movss 0x8912(%rip), %xmm0     # 0xc070
ucomiss 0x4(%rsp), %xmm0
jbe 0x3833
testq %rbx, %rbx
jne 0x3777
movq 0xf863(%rip), %rsi      # 0x12fd8
jmp 0x377f
leaq 0x130(%rsp), %rsi
leaq 0x60(%rsp), %rdi
callq 0x2951
leaq 0x20(%rsp), %rdi
leaq 0x60(%rsp), %rsi
movss 0x4(%rsp), %xmm0
callq 0x45e8
leaq 0x60(%rsp), %rdi
callq 0x3f7a
leaq 0x60(%rsp), %rdi
leaq 0x20(%rsp), %rsi
pushq $0x2
popq %rcx
movq 0x18(%rsp), %rdx
movss 0x4(%rsp), %xmm0
movss 0xc(%rsp), %xmm1
callq 0x43ec
leaq 0x60(%rsp), %rdi
callq 0x44a8
leaq 0x60(%rsp), %rdi
callq 0x45b4
leaq 0x20(%rsp), %rdi
callq 0x3fe0
leaq 0x130(%rsp), %rdi
callq 0x2070
xorl %eax, %eax
addq $0x338, %rsp            # imm = 0x338
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x0, 0x8(%rsp)
movl 0x8(%rsp), %edi
callq 0x3208
pushq $-0x1
popq %rdi
callq 0x3208
pushq $-0x1
popq %rdi
callq 0x3208
pushq $-0x1
popq %rdi
callq 0x3208
testq %rbx, %rbx
jne 0x3871
movq 0xf799(%rip), %rsi      # 0x12fd8
jmp 0x3879
movq 0xf7a8(%rip), %rdi      # 0x12ff0
leaq 0x8ce4(%rip), %rsi      # 0xc533
callq 0x21f0
movq %rax, %rdi
movq 0x10(%rsp), %rsi
callq 0x21f0
movq %rax, %rdi
callq 0x20e0
pushq $-0x1
popq %rdi
callq 0x2220
leaq 0x130(%rsp), %rsi
leaq 0x20(%rsp), %rdi
movq 0x50(%rsp), %rdx
callq 0x3179
movss 0x87e4(%rip), %xmm1     # 0xc074
movss 0x4(%rsp), %xmm0
ucomiss 0x87d3(%rip), %xmm0     # 0xc070
movss %xmm1, 0x10(%rsp)
movss %xmm1, 0x8(%rsp)
jne 0x391d
jp 0x391d
movq 0x38(%rsp), %rax
movq 0x40(%rsp), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
movss 0x87ae(%rip), %xmm3     # 0xc074
xorl %edx, %edx
movss 0x87a8(%rip), %xmm0     # 0xc078
cmpq %rcx, %rdx
je 0x3917
movaps %xmm0, %xmm1
xorl %esi, %esi
cmpq %rsi, %rcx
je 0x390b
xorps %xmm2, %xmm2
cmpq %rsi, %rdx
je 0x38ff
movq %rsi, %rdi
cmovgq %rdx, %rdi
movq %rsi, %r8
cmovlq %rdx, %r8
movq (%rax,%rdi,8), %rdi
movss (%rdi,%r8,4), %xmm2
maxss %xmm1, %xmm2
incq %rsi
movaps %xmm2, %xmm1
jmp 0x38da
minss %xmm3, %xmm1
incq %rdx
movaps %xmm1, %xmm3
jmp 0x38d0
movss %xmm3, 0x8(%rsp)
movq 0x20(%rsp), %rax
movq 0x28(%rsp), %rcx
xorl %ebp, %ebp
movss 0x8747(%rip), %xmm0     # 0xc078
movaps %xmm0, 0x50(%rsp)
movss 0x8736(%rip), %xmm0     # 0xc074
cmpq %rcx, %rax
je 0x398f
movss (%rax), %xmm1
movaps 0x50(%rsp), %xmm4
movaps %xmm4, %xmm2
cmpltps %xmm1, %xmm2
movaps %xmm1, %xmm3
cmpneqps %xmm0, %xmm3
andps %xmm2, %xmm3
movd %xmm3, %edx
movaps %xmm1, %xmm2
testb $0x1, %dl
jne 0x396c
movaps %xmm4, %xmm2
movss 0x4(%rsp), %xmm3
ucomiss %xmm1, %xmm3
sbbl $-0x1, %ebp
minss 0x10(%rsp), %xmm1
addq $0x4, %rax
movaps %xmm2, 0x50(%rsp)
movss %xmm1, 0x10(%rsp)
jmp 0x393e
movq 0xf622(%rip), %rdi      # 0x12fb8
leaq 0x8bdf(%rip), %rsi      # 0xc57c
callq 0x21f0
movq %rax, %rdi
movss 0x10(%rsp), %xmm0
callq 0x21a0
leaq 0x8c94(%rip), %rsi      # 0xc64b
movq %rax, %rdi
callq 0x21f0
movq %rax, %rdi
movaps 0x50(%rsp), %xmm0
callq 0x21a0
leaq 0x87a2(%rip), %rsi      # 0xc175
movq %rax, %rdi
callq 0x21f0
movq %rax, %rdi
callq 0x20e0
movss 0x4(%rsp), %xmm0
ucomiss 0x8680(%rip), %xmm0     # 0xc070
jne 0x3a90
jp 0x3a90
movq 0xf5b5(%rip), %rdi      # 0x12fb8
leaq 0x8b44(%rip), %rsi      # 0xc54e
callq 0x21f0
movq 0x40(%rsp), %rsi
subq 0x38(%rsp), %rsi
sarq $0x3, %rsi
movq %rax, %rdi
callq 0x2170
leaq 0x8b5f(%rip), %rsi      # 0xc58b
movq %rax, %rdi
callq 0x21f0
movq %rax, %rdi
movss 0x8(%rsp), %xmm0
callq 0x21a0
movq %rax, %rdi
callq 0x20e0
leaq 0x60(%rsp), %rdi
leaq 0x20(%rsp), %rsi
pushq $0x2
popq %rcx
movq 0x18(%rsp), %rdx
movss 0x8(%rsp), %xmm0
movss 0xc(%rsp), %xmm1
callq 0x46c6
leaq 0x60(%rsp), %rdi
callq 0x4780
leaq 0x60(%rsp), %rdi
callq 0x488c
xorl %edi, %edi
callq 0x2220
pushq $-0x1
popq %rdi
callq 0x3208
movq 0xf521(%rip), %rdi      # 0x12fb8
leaq 0x8aa9(%rip), %rsi      # 0xc547
callq 0x21f0
movq 0x40(%rsp), %rsi
subq 0x38(%rsp), %rsi
sarq $0x3, %rsi
movq %rax, %rdi
callq 0x2170
leaq 0x8aa4(%rip), %rsi      # 0xc564
movq %rax, %rdi
callq 0x21f0
movq %rax, %rdi
movl %ebp, %esi
callq 0x22f0
leaq 0x8a98(%rip), %rsi      # 0xc571
movq %rax, %rdi
callq 0x21f0
movq 0x40(%rsp), %rcx
subq 0x38(%rsp), %rcx
sarq $0x3, %rcx
leaq -0x1(%rcx), %rsi
imulq %rcx, %rsi
shrq %rsi
movq %rax, %rdi
callq 0x2170
leaq 0x8a6a(%rip), %rsi      # 0xc573
movq %rax, %rdi
callq 0x21f0
movq %rax, %rdi
callq 0x20e0
leaq 0x110(%rsp), %rdi
leaq 0x20(%rsp), %rsi
movss 0x4(%rsp), %xmm0
callq 0x48c4
leaq 0x60(%rsp), %rdi
leaq 0x110(%rsp), %rsi
pushq $0x2
popq %rcx
movq 0x18(%rsp), %rdx
movss 0x4(%rsp), %xmm0
movss 0xc(%rsp), %xmm1
callq 0x43ec
leaq 0x60(%rsp), %rdi
callq 0x44a8
leaq 0x60(%rsp), %rdi
callq 0x45b4
leaq 0x110(%rsp), %rdi
callq 0x3fe0
jmp 0x3a81
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x45b4
jmp 0x3b8f
movq %rax, %rbx
leaq 0x110(%rsp), %rdi
callq 0x3fe0
jmp 0x3bb6
jmp 0x3bb3
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x488c
jmp 0x3bb6
jmp 0x3bb3
jmp 0x3c1d
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x49a8
jmp 0x3c06
jmp 0x3bc6
jmp 0x3bf9
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x45b4
jmp 0x3bfc
jmp 0x3bf9
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x3f7a
jmp 0x3c06
jmp 0x3bec
jmp 0x3bec
jmp 0x3bec
movq %rax, %rbx
jmp 0x3c06
jmp 0x3c33
jmp 0x3c1d
jmp 0x3c1d
jmp 0x3c33
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x3fe0
leaq 0x130(%rsp), %rdi
callq 0x2070
jmp 0x3c43
jmp 0x3c1d
jmp 0x3c1d
jmp 0x3c33
jmp 0x3c1d
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x2388
jmp 0x3c36
jmp 0x3c33
movq %rax, %rbx
jmp 0x3c43
movq %rax, %rbx
leaq 0x130(%rsp), %rdi
callq 0x2388
movq %rbx, %rdi
callq 0x2300