// File: qmmlib[P]QmmLibrary/linear.cpp
// Function: group_classes(problem const*, int*, int**, int**, int**, int*)
static void group_classes(const problem *prob, int *nr_class_ret, int **label_ret, int **start_ret, int **count_ret, int *perm)
{
	int l = prob->l;
	int max_nr_class = 16;
	int nr_class = 0;
	int *label = Malloc(int,max_nr_class);
	int *count = Malloc(int,max_nr_class);
	int *data_label = Malloc(int,l);
	int i;

	for(i=0;i<l;i++)
	{
		int this_label = (int)prob->y[i];
		int j;
		for(j=0;j<nr_class;j++)
		{
			if(this_label == label[j])
			{
				++count[j];
				break;
			}
		}
		data_label[i] = j;
		if(j == nr_class)
		{
			if(nr_class == max_nr_class)
			{
				max_nr_class *= 2;
				label = (int *)realloc(label,max_nr_class*sizeof(int));
				count = (int *)realloc(count,max_nr_class*sizeof(int));
			}
			label[nr_class] = this_label;
			count[nr_class] = 1;
			++nr_class;
		}
	}

	int *start = Malloc(int,nr_class);
	start[0] = 0;
	for(i=1;i<nr_class;i++)
		start[i] = start[i-1]+count[i-1];
	for(i=0;i<l;i++)
	{
		perm[start[data_label[i]]] = i;
		++start[data_label[i]];
	}
	start[0] = 0;
	for(i=1;i<nr_class;i++)
		start[i] = start[i-1]+count[i-1];

	*nr_class_ret = nr_class;
	*label_ret = label;
	*start_ret = start;
	*count_ret = count;
	free(data_label);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq -0x8(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x34(%rbp)
movl $0x10, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
movslq -0x38(%rbp), %rdi
shlq $0x2, %rdi
callq 0x33d0
movq %rax, -0x48(%rbp)
movslq -0x38(%rbp), %rdi
shlq $0x2, %rdi
callq 0x33d0
movq %rax, -0x50(%rbp)
movslq -0x34(%rbp), %rdi
shlq $0x2, %rdi
callq 0x33d0
movq %rax, -0x58(%rbp)
movl $0x0, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jge 0xb616
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x5c(%rbp), %rcx
cvttsd2si (%rax,%rcx,8), %eax
movl %eax, -0x60(%rbp)
movl $0x0, -0x64(%rbp)
movl -0x64(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jge 0xb590
movl -0x60(%rbp), %eax
movq -0x48(%rbp), %rcx
movslq -0x64(%rbp), %rdx
cmpl (%rcx,%rdx,4), %eax
jne 0xb583
movq -0x50(%rbp), %rax
movslq -0x64(%rbp), %rcx
movl (%rax,%rcx,4), %edx
addl $0x1, %edx
movl %edx, (%rax,%rcx,4)
jmp 0xb590
jmp 0xb585
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0xb558
movl -0x64(%rbp), %edx
movq -0x58(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movl -0x64(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jne 0xb606
movl -0x3c(%rbp), %eax
cmpl -0x38(%rbp), %eax
jne 0xb5e0
movl -0x38(%rbp), %eax
shll %eax
movl %eax, -0x38(%rbp)
movq -0x48(%rbp), %rdi
movslq -0x38(%rbp), %rsi
shlq $0x2, %rsi
callq 0x3490
movq %rax, -0x48(%rbp)
movq -0x50(%rbp), %rdi
movslq -0x38(%rbp), %rsi
shlq $0x2, %rsi
callq 0x3490
movq %rax, -0x50(%rbp)
movl -0x60(%rbp), %edx
movq -0x48(%rbp), %rax
movslq -0x3c(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x50(%rbp), %rax
movslq -0x3c(%rbp), %rcx
movl $0x1, (%rax,%rcx,4)
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0xb608
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0xb531
movslq -0x3c(%rbp), %rdi
shlq $0x2, %rdi
callq 0x33d0
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movl $0x0, (%rax)
movl $0x1, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jge 0xb676
movq -0x70(%rbp), %rax
movl -0x5c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %edx
movq -0x50(%rbp), %rax
movl -0x5c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
addl (%rax,%rcx,4), %edx
movq -0x70(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0xb638
movl $0x0, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jge 0xb6c7
movl -0x5c(%rbp), %edx
movq -0x30(%rbp), %rax
movq -0x70(%rbp), %rcx
movq -0x58(%rbp), %rsi
movslq -0x5c(%rbp), %rdi
movslq (%rsi,%rdi,4), %rsi
movslq (%rcx,%rsi,4), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x70(%rbp), %rax
movq -0x58(%rbp), %rcx
movslq -0x5c(%rbp), %rdx
movslq (%rcx,%rdx,4), %rcx
movl (%rax,%rcx,4), %edx
addl $0x1, %edx
movl %edx, (%rax,%rcx,4)
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0xb67d
movq -0x70(%rbp), %rax
movl $0x0, (%rax)
movl $0x1, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jge 0xb716
movq -0x70(%rbp), %rax
movl -0x5c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %edx
movq -0x50(%rbp), %rax
movl -0x5c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
addl (%rax,%rcx,4), %edx
movq -0x70(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0xb6d8
movl -0x3c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x48(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x70(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x50(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x58(%rbp), %rdi
callq 0x3370
addq $0x70, %rsp
popq %rbp
retq
nop