// File: /workspace/github_c_makefile_star2_O2/olcaytaner[P]Isell/multiplemodel.c
// Function: mmelin1
int mmelin1(Instanceptr* traindata)
{
	/*!Last Changed 11.04.2005*/
	matrix X, r, w, bestw, *models;
	Instanceptr removed = NULL, modelremoved = NULL, tmp;
	int i, finished = 1, iteration, size, j, mindatasize, modelcount, first;
	double totalerror, *residuals, threshold, upperbound, upperbefore, bestthreshold, ratio, bestratio;
	size = data_size(*traindata);
 mindatasize = size / 20;
	modelcount = 0;
	while (finished)
	 {
		 iteration = size / mindatasize;
			bestratio = 0;
			first = 1;
		 for (i = 0; i < iteration - 2; i++)
			 {
     create_regression_matrices(*traindata, &X, &r);
    	w = multivariate_regression(X, r);
	  		matrix_free(X);
		  	matrix_free(r);
    	size = data_size(*traindata);
					residuals = safemalloc(size * sizeof(double), "mmelin", 20);
					j = 0;
					totalerror = 0;
					tmp = *traindata;
					while (tmp)
					 {
						 residuals[j] = fabs(linear_fit_value(w, tmp) - give_regressionvalue(tmp));
							totalerror += residuals[j] * residuals[j]; 
						 tmp = tmp->next;
							j++;
					 }
					totalerror /= j;
     upperbound = srm_regression(totalerror, current_dataset->multifeaturecount, size, 1.0, 1.0);
					if (i != 0)
						 ratio = upperbefore / upperbound;
					else
						 ratio = 0;
					upperbefore = upperbound;
     if (ratio > bestratio)
					 {
						 if (!first)
								 matrix_free(bestw);
       bestw = matrix_copy(w);
							bestratio = ratio;
							bestthreshold = threshold;
					 }
     qsort(residuals, size, sizeof(double), sort_function_double_ascending);
					threshold = (residuals[size - mindatasize - 1] + residuals[size - mindatasize]) / 2;
     remove_instances_according_to_threshold(traindata, &modelremoved, threshold, w, '>');
					matrix_free(w);
			 }
			merge_instancelist(traindata, modelremoved);
   remove_instances_according_to_threshold(traindata, &removed, bestthreshold, bestw, '<');
			modelremoved = NULL;
			modelcount++;
			models = alloc(models, modelcount * sizeof(matrix), modelcount);
			models[modelcount - 1] = matrix_copy(bestw);
			matrix_free(bestw);
			size = data_size(*traindata);
			if (size <= 2 * mindatasize)
				 finished = 0;
	 }
	merge_instancelist(traindata, removed);
	removed = NULL;
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq %rdi, %rbx
leaq 0x28(%rsp), %rax
andq $0x0, (%rax)
movq %rsp, %rax
andq $0x0, (%rax)
movq (%rdi), %rdi
callq 0x2c3cc
movl %eax, %ecx
pushq $0x14
popq %rsi
cltd
idivl %esi
movq %rax, 0x18(%rsp)
addl %eax, %eax
movl %eax, 0xc(%rsp)
pushq $0x1
popq %rax
xorl %r14d, %r14d
movq %rbx, 0x98(%rsp)
testl %eax, %eax
je 0x44a9b
movq %r14, 0x78(%rsp)
movl %ecx, %eax
cltd
idivl 0x18(%rsp)
movl %eax, %ecx
cmpl $0x3, %eax
pushq $0x2
popq %rax
cmovll %eax, %ecx
addl $-0x2, %ecx
movl %ecx, 0x10(%rsp)
xorl %r14d, %r14d
xorpd %xmm0, %xmm0
movsd %xmm0, 0x20(%rsp)
cmpl 0x10(%rsp), %r14d
je 0x449fa
movl %r14d, 0x14(%rsp)
movq (%rbx), %rdi
leaq 0x40(%rsp), %rsi
leaq 0x30(%rsp), %rdx
callq 0x6cf16
movq 0x40(%rsp), %rdi
movq 0x48(%rsp), %rsi
movq 0x30(%rsp), %rdx
movq 0x38(%rsp), %rcx
callq 0x6ca8d
movq %rax, %r13
movq %rdx, %r15
movq 0x40(%rsp), %rdi
movq 0x48(%rsp), %rsi
callq 0x3929f
movq 0x30(%rsp), %rdi
movq 0x38(%rsp), %rsi
callq 0x3929f
movq (%rbx), %rdi
callq 0x2c3cc
movl %eax, %ebp
cltq
movq %rax, 0xb0(%rsp)
leaq (,%rax,8), %rdi
leaq 0x55daf(%rip), %rsi     # 0x9a624
pushq $0x14
popq %rdx
callq 0x34f59
movq %rax, %r12
xorpd %xmm1, %xmm1
xorl %r14d, %r14d
movq (%rbx), %rbx
testq %rbx, %rbx
je 0x448e4
movq %r13, %rdi
movq %r15, %rsi
movq %rbx, %rdx
movapd %xmm1, 0x60(%rsp)
callq 0x6ce0c
movapd %xmm0, 0x50(%rsp)
movq %rbx, %rdi
callq 0x2b4a0
movapd 0x60(%rsp), %xmm1
movapd 0x50(%rsp), %xmm2
subsd %xmm0, %xmm2
movapd %xmm2, %xmm0
andpd 0x51913(%rip), %xmm0    # 0x961e0
movlpd %xmm0, (%r12,%r14,8)
mulsd %xmm2, %xmm2
addsd %xmm2, %xmm1
addq $0x10, %rbx
incq %r14
jmp 0x44887
cvtsi2sd %r14d, %xmm0
divsd %xmm0, %xmm1
leaq 0x88f7c(%rip), %rax     # 0xcd870
movq (%rax), %rax
movl 0x1c0(%rax), %edi
movapd %xmm1, %xmm0
movl %ebp, %esi
movsd 0x50c15(%rip), %xmm1    # 0x95520
movapd %xmm1, %xmm2
callq 0x41cba
xorpd %xmm1, %xmm1
movl 0x14(%rsp), %r14d
testl %r14d, %r14d
je 0x4492f
movsd 0xa0(%rsp), %xmm1
divsd %xmm0, %xmm1
movsd %xmm0, 0x60(%rsp)
ucomisd 0x20(%rsp), %xmm1
movq 0x98(%rsp), %rbx
jbe 0x44984
movq %r13, %rdi
movq %r15, %rsi
movsd %xmm1, 0x50(%rsp)
callq 0x383f4
movq %rax, 0x90(%rsp)
movq %rdx, 0x80(%rsp)
movsd 0xa8(%rsp), %xmm0
movsd %xmm0, 0x88(%rsp)
movsd 0x50(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
movq %r12, %rdi
movq 0xb0(%rsp), %rsi
pushq $0x8
popq %rdx
leaq -0xf5da(%rip), %rcx     # 0x353bf
callq 0x4240
subl 0x18(%rsp), %ebp
movslq %ebp, %rax
movsd -0x8(%r12,%rax,8), %xmm0
addsd (%r12,%rax,8), %xmm0
mulsd 0x51366(%rip), %xmm0    # 0x95d20
movq %rbx, %rdi
movq %rsp, %rsi
movsd %xmm0, 0xa8(%rsp)
movq %r13, %rdx
movq %r15, %rcx
pushq $0x3e
popq %r8
callq 0x4466c
movq %r13, %rdi
movq %r15, %rsi
callq 0x3929f
incl %r14d
movsd 0x60(%rsp), %xmm0
movsd %xmm0, 0xa0(%rsp)
jmp 0x447f3
movq (%rsp), %rsi
movq %rbx, %rdi
callq 0x2c6e4
movq %rbx, %rdi
leaq 0x28(%rsp), %rsi
movsd 0x88(%rsp), %xmm0
movq 0x90(%rsp), %r13
movq %r13, %rdx
movq 0x80(%rsp), %rbp
movq %rbp, %rcx
pushq $0x3c
popq %r8
callq 0x4466c
andq $0x0, (%rsp)
movq 0x78(%rsp), %r15
leaq 0x1(%r15), %r14
movq %r14, %rsi
shlq $0x4, %rsi
movq 0x70(%rsp), %rdi
movl %r14d, %edx
callq 0x34f30
movq %rax, %r12
shlq $0x4, %r15
movq %r13, %rdi
movq %rbp, %rsi
callq 0x383f4
movq %rax, (%r12,%r15)
movq %r12, 0x70(%rsp)
movq %rdx, 0x8(%r12,%r15)
movq %r13, %rdi
movq %rbp, %rsi
callq 0x3929f
movq (%rbx), %rdi
callq 0x2c3cc
movl %eax, %ecx
xorl %eax, %eax
cmpl 0xc(%rsp), %ecx
setg %al
jmp 0x447c0
movq 0x28(%rsp), %rsi
movq %rbx, %rdi
callq 0x2c6e4
xorl %eax, %eax
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq