// File: /workspace/github_c_makefile_star2_O3/olcaytaner[P]Isell/softregtree.c
// Function: gradient_descent_soft_regtree
void gradient_descent_soft_regtree(Regressionnodeptr rootnode, Regressionnodeptr node, Softregtree_parameterptr param, double eta, double lambda)
{
 int i, j, k, *array, datasize;
 double o, r, multiplier, delta, feature_value;
 Instanceptr inst; 
 Regressionnodeptr tmpnode;
 datasize = data_size(rootnode->instances);
 node->w = random_matrix(current_dataset->multifeaturecount, 1, -0.01, +0.01);
 if (param->leaftype == CONSTANTLEAF)
  {
   node->left->regressionvalue = produce_random_value(-0.01, +0.01);
   node->right->regressionvalue = produce_random_value(-0.01, +0.01);
  }
 else
  {
   node->left->w = random_matrix(current_dataset->multifeaturecount, 1, -0.01, +0.01);
   node->right->w = random_matrix(current_dataset->multifeaturecount, 1, -0.01, +0.01);
  }
 for (i = 0; i < param->epochs; i++)
  {
   array = random_array(datasize);
   for (j = 0; j < datasize; j++)
    {
     inst = data_x(rootnode->instances, array[j]);
     o = soft_regtree_output(rootnode, inst);
     r = give_regressionvalue(inst);
     multiplier = eta * (r - o);
     tmpnode = node;
     while (tmpnode->parent)
      {
       multiplier *= tmpnode->weight;
       tmpnode = tmpnode->parent;
      }
     if (param->leaftype == CONSTANTLEAF)
      {
       node->left->regressionvalue += multiplier * node->left->weight;
       node->right->regressionvalue += multiplier * node->right->weight;
      }
     for (k = 0; k < current_dataset->multifeaturecount; k++)
      {      
       if (k != 0)
         feature_value = real_feature(inst, k - 1);
       else
         feature_value = 1;
       delta = multiplier * feature_value;
       if (param->regularization == NO_REGULARIZATION)
         node->w.values[k][0] += delta * (node->left->output - node->right->output) * node->left->weight * node->right->weight;
       else
         if (param->regularization == L1_REGULARIZATION)
          {
           if (feature_value > 0)
             node->w.values[k][0] += ((1 - lambda) * delta * (node->left->output - node->right->output) * node->left->weight * node->right->weight) / datasize + eta * lambda / current_dataset->multifeaturecount;
           else
             node->w.values[k][0] += ((1 - lambda) * delta * (node->left->output - node->right->output) * node->left->weight * node->right->weight) / datasize - eta * lambda / current_dataset->multifeaturecount;
          }
         else
           node->w.values[k][0] += ((1 - lambda) * delta * (node->left->output - node->right->output) * node->left->weight * node->right->weight) / datasize + (eta * lambda * feature_value) / current_dataset->multifeaturecount;           
       if (param->leaftype != CONSTANTLEAF)
        { 
         node->left->w.values[k][0] += delta * node->left->weight;
         node->right->w.values[k][0] += delta * node->right->weight;
        }
      }
    }
   safe_free(array);   
   eta = eta * param->etadecrease;
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movsd %xmm1, 0x20(%rsp)
movsd %xmm0, 0x10(%rsp)
movq %rdx, %rbx
movq %rsi, %r14
movq %rdi, 0x48(%rsp)
movq 0x20(%rdi), %rdi
callq 0x30309
movl %eax, 0xc(%rsp)
leaq 0x4addf(%rip), %rbp     # 0xd5870
movq (%rbp), %rax
movl 0x1c0(%rax), %edi
movsd 0x1b315(%rip), %xmm0    # 0xa5db8
movsd 0x1b315(%rip), %xmm1    # 0xa5dc0
movl $0x1, %esi
callq 0x3ef18
movq %rax, 0x30(%r14)
movq %rdx, 0x38(%r14)
cmpl $0x0, (%rbx)
je 0x8ab23
movq (%r14), %r15
movq (%rbp), %rax
movl 0x1c0(%rax), %edi
movsd 0x1b2e1(%rip), %xmm0    # 0xa5db8
movsd 0x1b2e1(%rip), %xmm1    # 0xa5dc0
movl $0x1, %esi
callq 0x3ef18
movq %rax, 0x30(%r15)
movq %rdx, 0x38(%r15)
movq 0x8(%r14), %r15
movq (%rbp), %rax
movl 0x1c0(%rax), %edi
movl $0x1, %esi
movsd 0x1b2ac(%rip), %xmm0    # 0xa5db8
movsd 0x1b2ac(%rip), %xmm1    # 0xa5dc0
callq 0x3ef18
movq %rax, 0x30(%r15)
movq %rdx, 0x38(%r15)
jmp 0x8ab5e
movsd 0x1b28d(%rip), %xmm0    # 0xa5db8
movsd 0x1b28d(%rip), %xmm1    # 0xa5dc0
callq 0x3af6a
movq (%r14), %rax
movsd %xmm0, 0x70(%rax)
movsd 0x1b270(%rip), %xmm0    # 0xa5db8
movsd 0x1b270(%rip), %xmm1    # 0xa5dc0
callq 0x3af6a
movq 0x8(%r14), %rax
movsd %xmm0, 0x70(%rax)
cmpl $0x0, 0x4(%rbx)
jle 0x8ae3b
movsd 0x1a9b0(%rip), %xmm0    # 0xa5520
movl 0xc(%rsp), %eax
xorps %xmm1, %xmm1
cvtsi2sd %eax, %xmm1
movapd %xmm1, 0x50(%rsp)
subsd 0x20(%rsp), %xmm0
movsd %xmm0, 0x30(%rsp)
movl %eax, %eax
movq %rax, 0x40(%rsp)
xorl %eax, %eax
movq %rax, 0x38(%rsp)
movl 0xc(%rsp), %r15d
movl %r15d, %edi
callq 0x3afe4
movq %rax, 0x28(%rsp)
testl %r15d, %r15d
jle 0x8ae10
movsd 0x10(%rsp), %xmm0
mulsd 0x20(%rsp), %xmm0
movapd %xmm0, 0x60(%rsp)
xorl %r12d, %r12d
movq 0x48(%rsp), %r15
movq 0x20(%r15), %rdi
movq 0x28(%rsp), %rax
movl (%rax,%r12,4), %esi
callq 0x31851
movq %rax, %r13
movq %r15, %rdi
movq %rax, %rsi
callq 0x8a924
movsd %xmm0, 0x18(%rsp)
movq %r13, %rdi
callq 0x2f35e
movapd %xmm0, %xmm5
subsd 0x18(%rsp), %xmm5
mulsd 0x10(%rsp), %xmm5
movq 0x18(%r14), %rax
testq %rax, %rax
je 0x8ac2b
movq %r14, %rcx
mulsd 0x48(%rcx), %xmm5
movq %rax, %rcx
movq 0x18(%rax), %rax
testq %rax, %rax
jne 0x8ac1a
cmpl $0x0, (%rbx)
jne 0x8ac5d
movq (%r14), %rax
movsd 0x48(%rax), %xmm0
mulsd %xmm5, %xmm0
addsd 0x70(%rax), %xmm0
movsd %xmm0, 0x70(%rax)
movq 0x8(%r14), %rax
movsd 0x48(%rax), %xmm0
mulsd %xmm5, %xmm0
addsd 0x70(%rax), %xmm0
movsd %xmm0, 0x70(%rax)
movq (%rbp), %rax
cmpl $0x0, 0x1c0(%rax)
jle 0x8ae02
xorl %r15d, %r15d
movsd %xmm5, 0x18(%rsp)
movsd 0x1a8a1(%rip), %xmm0    # 0xa5520
testq %r15, %r15
je 0x8ac96
leal -0x1(%r15), %esi
movq %r13, %rdi
callq 0x2ed6a
movsd 0x18(%rsp), %xmm5
movapd %xmm5, %xmm1
mulsd %xmm0, %xmm1
movl 0x20(%rbx), %eax
cmpl $0x1, %eax
je 0x8acd6
testl %eax, %eax
jne 0x8ad3a
movq (%r14), %rcx
movq 0x8(%r14), %rax
movsd 0x40(%rcx), %xmm0
subsd 0x40(%rax), %xmm0
mulsd %xmm1, %xmm0
mulsd 0x48(%rcx), %xmm0
movq 0x38(%r14), %rdx
mulsd 0x48(%rax), %xmm0
jmp 0x8ad9e
ucomisd 0x1b02a(%rip), %xmm0    # 0xa5d08
movsd 0x30(%rsp), %xmm2
movq (%r14), %rcx
movq 0x8(%r14), %rax
movsd 0x40(%rcx), %xmm0
subsd 0x40(%rax), %xmm0
mulsd %xmm1, %xmm2
mulsd %xmm2, %xmm0
mulsd 0x48(%rcx), %xmm0
mulsd 0x48(%rax), %xmm0
divsd 0x50(%rsp), %xmm0
movq (%rbp), %rdx
xorps %xmm2, %xmm2
cvtsi2sdl 0x1c0(%rdx), %xmm2
movapd 0x60(%rsp), %xmm3
divsd %xmm2, %xmm3
movq 0x38(%r14), %rdx
movq (%rdx,%r15,8), %rdx
movsd (%rdx), %xmm2
jbe 0x8adac
addsd %xmm3, %xmm0
jmp 0x8adb0
movsd 0x30(%rsp), %xmm2
movq (%r14), %rcx
movq 0x8(%r14), %rax
movsd 0x40(%rcx), %xmm3
subsd 0x40(%rax), %xmm3
mulsd %xmm1, %xmm2
mulsd %xmm2, %xmm3
mulsd 0x48(%rcx), %xmm3
movq (%rbp), %rdx
xorps %xmm2, %xmm2
cvtsi2sdl 0x1c0(%rdx), %xmm2
movsd 0x48(%rax), %xmm4
unpcklpd 0x60(%rsp), %xmm4       # xmm4 = xmm4[0],mem[0]
unpcklpd %xmm0, %xmm3            # xmm3 = xmm3[0],xmm0[0]
mulpd %xmm4, %xmm3
movapd 0x50(%rsp), %xmm0
unpcklpd %xmm2, %xmm0            # xmm0 = xmm0[0],xmm2[0]
divpd %xmm0, %xmm3
movapd %xmm3, %xmm0
unpckhpd %xmm3, %xmm0            # xmm0 = xmm0[1],xmm3[1]
addsd %xmm3, %xmm0
movq 0x38(%r14), %rdx
movq (%rdx,%r15,8), %rdx
addsd (%rdx), %xmm0
movsd %xmm0, (%rdx)
jmp 0x8adb8
subsd %xmm3, %xmm0
addsd %xmm0, %xmm2
movsd %xmm2, (%rdx)
cmpl $0x0, (%rbx)
je 0x8adeb
movq 0x38(%rcx), %rdx
movq (%rdx,%r15,8), %rdx
movsd 0x48(%rcx), %xmm0
mulsd %xmm1, %xmm0
addsd (%rdx), %xmm0
movsd %xmm0, (%rdx)
movq 0x38(%rax), %rcx
mulsd 0x48(%rax), %xmm1
movq (%rcx,%r15,8), %rax
addsd (%rax), %xmm1
movsd %xmm1, (%rax)
incq %r15
movq (%rbp), %rax
movslq 0x1c0(%rax), %rax
cmpq %rax, %r15
jl 0x8ac77
incq %r12
cmpq 0x40(%rsp), %r12
jne 0x8abcb
movq 0x28(%rsp), %rdi
callq 0x3a180
movsd 0x10(%rsp), %xmm0
mulsd 0x10(%rbx), %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x38(%rsp), %rax
incl %eax
cmpl 0x4(%rbx), %eax
jl 0x8ab96
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq