// File: /workspace/github_c_makefile_star2_O2/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 0x2c3cc
movl %eax, 0xc(%rsp)
leaq 0x504f3(%rip), %rbp     # 0xcd870
movq (%rbp), %rax
movl 0x1c0(%rax), %edi
pushq $0x1
popq %rsi
movsd 0x18a2e(%rip), %xmm0    # 0x95dc0
movsd 0x18a2e(%rip), %xmm1    # 0x95dc8
callq 0x393f5
movq %rax, 0x30(%r14)
movq %rdx, 0x38(%r14)
cmpl $0x0, (%rbx)
je 0x7d40d
movq (%r14), %r15
movq (%rbp), %rax
movl 0x1c0(%rax), %edi
pushq $0x1
popq %r12
movsd 0x189fb(%rip), %xmm0    # 0x95dc0
movsd 0x189fb(%rip), %xmm1    # 0x95dc8
movl %r12d, %esi
callq 0x393f5
movq %rax, 0x30(%r15)
movq %rdx, 0x38(%r15)
movq 0x8(%r14), %r15
movq (%rbp), %rax
movl 0x1c0(%rax), %edi
movl %r12d, %esi
movsd 0x189ca(%rip), %xmm0    # 0x95dc0
movsd 0x189ca(%rip), %xmm1    # 0x95dc8
callq 0x393f5
movq %rax, 0x30(%r15)
movq %rdx, 0x38(%r15)
jmp 0x7d448
movsd 0x189ab(%rip), %xmm0    # 0x95dc0
movsd 0x189ab(%rip), %xmm1    # 0x95dc8
callq 0x35cae
movq (%r14), %rax
movsd %xmm0, 0x70(%rax)
movsd 0x1898e(%rip), %xmm0    # 0x95dc0
movsd 0x1898e(%rip), %xmm1    # 0x95dc8
callq 0x35cae
movq 0x8(%r14), %rax
movsd %xmm0, 0x70(%rax)
movsd 0x180d0(%rip), %xmm0    # 0x95520
subsd 0x20(%rsp), %xmm0
movsd %xmm0, 0x58(%rsp)
movl 0xc(%rsp), %eax
cvtsi2sd %eax, %xmm0
movapd %xmm0, 0x60(%rsp)
xorl %ecx, %ecx
testl %eax, %eax
cmovlel %ecx, %eax
movq %rax, 0x50(%rsp)
cmpl 0x4(%rbx), %ecx
jge 0x7d6fb
movq %rcx, 0x40(%rsp)
movl 0xc(%rsp), %edi
callq 0x35cf7
movq %rax, 0x28(%rsp)
movsd 0x10(%rsp), %xmm0
mulsd 0x20(%rsp), %xmm0
movapd %xmm0, 0x30(%rsp)
xorl %r12d, %r12d
cmpq 0x50(%rsp), %r12
je 0x7d6d4
movq 0x48(%rsp), %r15
movq 0x20(%r15), %rdi
movq 0x28(%rsp), %rax
movl (%rax,%r12,4), %esi
callq 0x2d761
movq %rax, %r13
movq %r15, %rdi
movq %rax, %rsi
callq 0x7d220
movsd %xmm0, 0x18(%rsp)
movq %r13, %rdi
callq 0x2b4a0
movapd %xmm0, %xmm5
subsd 0x18(%rsp), %xmm5
mulsd 0x10(%rsp), %xmm5
movq %r14, %rax
movq 0x18(%rax), %rcx
testq %rcx, %rcx
je 0x7d50b
mulsd 0x48(%rax), %xmm5
movq %rcx, %rax
jmp 0x7d4f8
cmpl $0x0, (%rbx)
jne 0x7d53d
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
xorl %r15d, %r15d
movsd %xmm5, 0x18(%rsp)
movslq 0x1c0(%rax), %rcx
cmpq %rcx, %r15
jge 0x7d6cc
movsd 0x17fbe(%rip), %xmm0    # 0x95520
testq %r15, %r15
je 0x7d57d
leal -0x1(%r15), %esi
movq %r13, %rdi
callq 0x2aea2
movsd 0x18(%rsp), %xmm5
movq (%rbp), %rax
movapd %xmm5, %xmm1
mulsd %xmm0, %xmm1
movl 0x20(%rbx), %ecx
movsd 0x58(%rsp), %xmm2
mulsd %xmm1, %xmm2
cmpl $0x1, %ecx
je 0x7d5c3
testl %ecx, %ecx
jne 0x7d616
movq (%r14), %rdx
movq 0x8(%r14), %rcx
movsd 0x40(%rdx), %xmm0
subsd 0x40(%rcx), %xmm0
mulsd %xmm1, %xmm0
mulsd 0x48(%rdx), %xmm0
movq 0x38(%r14), %rsi
mulsd 0x48(%rcx), %xmm0
jmp 0x7d669
ucomisd 0x1874d(%rip), %xmm0    # 0x95d18
movq (%r14), %rdx
movq 0x8(%r14), %rcx
movsd 0x40(%rdx), %xmm0
subsd 0x40(%rcx), %xmm0
mulsd %xmm0, %xmm2
mulsd 0x48(%rdx), %xmm2
mulsd 0x48(%rcx), %xmm2
divsd 0x60(%rsp), %xmm2
movq 0x38(%r14), %rsi
movq (%rsi,%r15,8), %rsi
movsd (%rsi), %xmm0
jbe 0x7d673
cvtsi2sdl 0x1c0(%rax), %xmm3
movapd 0x30(%rsp), %xmm4
divsd %xmm3, %xmm4
addsd %xmm4, %xmm2
jmp 0x7d689
movq (%r14), %rdx
movq 0x8(%r14), %rcx
movsd 0x40(%rdx), %xmm3
subsd 0x40(%rcx), %xmm3
mulsd %xmm3, %xmm2
mulsd 0x48(%rdx), %xmm2
cvtsi2sdl 0x1c0(%rax), %xmm3
movsd 0x48(%rcx), %xmm4
unpcklpd 0x30(%rsp), %xmm4       # xmm4 = xmm4[0],mem[0]
unpcklpd %xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0]
mulpd %xmm4, %xmm2
movapd 0x60(%rsp), %xmm0
unpcklpd %xmm3, %xmm0            # xmm0 = xmm0[0],xmm3[0]
divpd %xmm0, %xmm2
movapd %xmm2, %xmm0
unpckhpd %xmm2, %xmm0            # xmm0 = xmm0[1],xmm2[1]
addsd %xmm2, %xmm0
movq 0x38(%r14), %rsi
movq (%rsi,%r15,8), %rsi
addsd (%rsi), %xmm0
jmp 0x7d68d
cvtsi2sdl 0x1c0(%rax), %xmm3
movapd 0x30(%rsp), %xmm4
divsd %xmm3, %xmm4
subsd %xmm4, %xmm2
addsd %xmm2, %xmm0
movsd %xmm0, (%rsi)
cmpl $0x0, (%rbx)
je 0x7d6c4
movq 0x38(%rdx), %rsi
movq (%rsi,%r15,8), %rsi
movsd 0x48(%rdx), %xmm0
mulsd %xmm1, %xmm0
addsd (%rsi), %xmm0
movsd %xmm0, (%rsi)
movq 0x38(%rcx), %rdx
mulsd 0x48(%rcx), %xmm1
movq (%rdx,%r15,8), %rcx
addsd (%rcx), %xmm1
movsd %xmm1, (%rcx)
incq %r15
jmp 0x7d54a
incq %r12
jmp 0x7d4a7
movq 0x28(%rsp), %rdi
callq 0x34ff7
movsd 0x10(%rsp), %xmm0
mulsd 0x10(%rbx), %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x40(%rsp), %rcx
incl %ecx
jmp 0x7d476
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq