// File: Ripser[P]ripser/ripser.cpp
// Function: void ripser<sparse_distance_matrix>::add_coboundary<std::priority_queue<diameter_entry_t, std::vector<diameter_entry_t, std::allocator<diameter_entry_t>>, greater_diameter_or_smaller_index_comp<diameter_entry_t>>>(compressed_sparse_matrix<diameter_entry_t>&, std::vector<std::pair<float, long>, std::allocator<std::pair<float, long>>> const&, unsigned long, unsigned short, unsigned long const&, std::priority_queue<diameter_entry_t, std::vector<diameter_entry_t, std::allocator<diameter_entry_t>>, greater_diameter_or_smaller_index_comp<diameter_entry_t>>&, std::priority_queue<diameter_entry_t, std::vector<diameter_entry_t, std::allocator<diameter_entry_t>>, greater_diameter_or_smaller_index_comp<diameter_entry_t>>&)
void add_coboundary(compressed_sparse_matrix<diameter_entry_t>& reduction_matrix,
	                    const std::vector<diameter_index_t>& columns_to_reduce,
	                    const size_t index_column_to_add, const coefficient_t factor,
	                    const size_t& dim, Column& working_reduction_column,
	                    Column& working_coboundary) {
		diameter_entry_t column_to_add(columns_to_reduce[index_column_to_add], factor);
		add_simplex_coboundary(column_to_add, dim, working_reduction_column, working_coboundary);

		for (diameter_entry_t simplex : reduction_matrix.subrange(index_column_to_add)) {
			set_coefficient(simplex, get_coefficient(simplex) * factor % modulus);
			add_simplex_coboundary(simplex, dim, working_reduction_column, working_coboundary);
		}
	}

// Assembly:
subq $0xb8, %rsp
movw %r8w, %ax
movq 0xc8(%rsp), %r8
movq 0xc0(%rsp), %r8
movq %rdi, 0xb0(%rsp)
movq %rsi, 0xa8(%rsp)
movq %rdx, 0xa0(%rsp)
movq %rcx, 0x98(%rsp)
movw %ax, 0x96(%rsp)
movq %r9, 0x88(%rsp)
movq 0xb0(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0xa0(%rsp), %rdi
movq 0x98(%rsp), %rsi
callq 0x18f30
movq %rax, %rsi
leaq 0x78(%rsp), %rdi
movzwl 0x96(%rsp), %edx
callq 0x18f50
movq 0x8(%rsp), %rdi
movq 0x78(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x80(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x88(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x60(%rsp)
movq 0xc0(%rsp), %rcx
movq 0xc8(%rsp), %r8
movss 0x68(%rsp), %xmm0
movq 0x70(%rsp), %rsi
leaq 0x60(%rsp), %rdx
callq 0x19800
movq 0xa8(%rsp), %rdi
movq 0x98(%rsp), %rsi
callq 0x1b6d0
movq %rax, 0x48(%rsp)
movq %rdx, 0x50(%rsp)
leaq 0x48(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rdi
callq 0x1b790
movq %rax, 0x40(%rsp)
movq 0x58(%rsp), %rdi
callq 0x1b7b0
movq %rax, 0x38(%rsp)
leaq 0x40(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x1a540
testb $0x1, %al
jne 0x19592
jmp 0x1963e
leaq 0x40(%rsp), %rdi
callq 0x1a580
movq (%rax), %rcx
movq %rcx, 0x28(%rsp)
movq 0x8(%rax), %rax
movq %rax, 0x30(%rsp)
leaq 0x28(%rsp), %rdi
callq 0x2a90
movq 0x8(%rsp), %rcx
movzwl %ax, %eax
movzwl 0x96(%rsp), %edx
imull %edx, %eax
movzwl 0x38(%rcx), %ecx
cltd
idivl %ecx
movw %dx, %ax
leaq 0x28(%rsp), %rdi
movzwl %ax, %esi
callq 0x2ac0
movq 0x8(%rsp), %rdi
movq 0x28(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x30(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x88(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x10(%rsp)
movq 0xc0(%rsp), %rcx
movq 0xc8(%rsp), %r8
movss 0x18(%rsp), %xmm0
movq 0x20(%rsp), %rsi
leaq 0x10(%rsp), %rdx
callq 0x19800
leaq 0x40(%rsp), %rdi
callq 0x1a5f0
jmp 0x1957a
addq $0xb8, %rsp
retq
nopw %cs:(%rax,%rax)