// File: /workspace/github_c_makefile_star2_O3/olcaytaner[P]Isell/algorithm.c
// Function: complexity_of_supervised_algorithm
int complexity_of_supervised_algorithm(int algorithm, void* model, void* parameters, Datasetptr current_dataset)
{
 /*!Last Changed 19.08.2007 added RBF and RBFREG algorithms*/
 /*!Last Changed 11.08.2007 added NAIVEBAYES algorithm*/
 /*!Last Changed 02.04.2007 added HMM algorithm*/
 /*!Last Changed 18.12.2005*/
 Ruleset r; 
 Regressionruleset regr;
 Quantizereg_parameterptr paramqua; 
 Model_ldaclassptr mlda;
 Decisionnodeptr* forest;
 Decisionnodeptr dtrootnode;
 Regressionnodeptr rtrootnode;
 Mlpparameters mlpparams;
 Rbf_parameter rbfparams;
 Svm_modelptr msvm;
 Hmmptr* hmmarray;
 Model_divsptr mdivs;
 int vectsize, i, j, numparameters, nSV, treecount, complexity;
 switch (algorithm)
  {
   case SELECTMAX     :return 1;/*Classno*/
   case ONEFEATURE    :return 4;/*Split feature, point, left and right mean*/
   case NEARESTMEAN   :return (current_dataset->featurecount - 1) * current_dataset->classno; /*Mean vectors for each class. Discrete features are NOT converted*/
   case GAUSSIAN      :return current_dataset->multifeaturecount * current_dataset->classno; /*Mean and vector and single variance for each class. Discrete features are converted.*/
   case SELECTAVERAGE :return 1;/*Mean regression value of trainset*/
   case LINEARREG     :return current_dataset->multifeaturecount; /*Weights for each feature and b. Discrete features are converted.*/
   case QUANTIZEREG   :paramqua = (Quantizereg_parameterptr) parameters;
                       if (current_dataset->featurecount > 2)
                         return 5 + paramqua->partitioncount * paramqua->partitioncount; /*minx, binx, miny, biny, partitioncount*/
                       else
                         return 3 + paramqua->partitioncount; /*minx, binx, partitioncount*/
   case KNN           :
   case KNNREG        :return data_size((Instanceptr)model) * current_dataset->featurecount + 1;/*number of data times number of features + 1 memory space to store k. Discrete features are not converted.*/
   case GPROCESSREG   :return ((Model_gprocessregressionptr)model)->size * current_dataset->multifeaturecount;/*N data samples + weights array of size N*/
   case LDT           :
   case C45           :
   case KTREE         :dtrootnode = (Decisionnodeptr)model;
                       return decisiontree_node_count(dtrootnode) * 2 + decisiontree_leaf_count(dtrootnode);/*For each node, univariate split, for each leaf, class label*/
   case RANDOMFOREST  :
   case KFOREST       :forest = (Decisionnodeptr*) model;
                       treecount = get_parameter_i("forestsize");
                       complexity = 0;
                       for (i = 0; i < treecount; i++)
                        {
                         dtrootnode = forest[i];
                         complexity += decisiontree_node_count(dtrootnode) * 2 + decisiontree_leaf_count(dtrootnode);
                        }
                       return complexity;
                       break;
   case SVMTREE       :forest = (Decisionnodeptr*) model;
                       if (get_parameter_l("multiclasstype") == ONE_VS_ONE)
                         treecount = current_dataset->classno * (current_dataset->classno - 1) / 2;
                       else
                         treecount = current_dataset->classno;
                       complexity = 0;
                       for (i = 0; i < treecount; i++)
                        {
                         dtrootnode = forest[i];
                         complexity += decisiontree_node_count(dtrootnode) * 2 + decisiontree_leaf_count(dtrootnode);
                        }
                       return complexity;
   case QDACLASS      :return current_dataset->classno * ((current_dataset->multifeaturecount - 1) * (current_dataset->multifeaturecount) / 2 + (current_dataset->multifeaturecount - 1) + 1);
   case LDACLASS      :mlda = (Model_ldaclassptr)model;
                       vectsize = (mlda->newfeaturecount - 1) * (current_dataset->multifeaturecount - 1);/*Size of eigenvectors plus*/
                       return vectsize + current_dataset->classno * mlda->newfeaturecount; /*Weight vector and bias for each class*/
   case NAIVEBAYES    :numparameters = current_dataset->classno;
                       for (i = 0; i < current_dataset->featurecount; i++)
                         switch (current_dataset->features[i].type)
                          {
                           case INTEGER:
                           case    REAL:numparameters += current_dataset->classno + 1;
                                        break;
                           case  STRING:numparameters += current_dataset->classno * current_dataset->features[i].valuecount;
                                        break;
                          }
                       return numparameters;
   case LOGISTIC      :return current_dataset->multifeaturecount * current_dataset->classno; /*Mean vectors and bias for each class. Discrete features are converted*/
   case IREP          :
   case IREP2         :
   case RIPPER        :
   case C45RULES      :
   case MULTIRIPPER   :
   case HYBRIDRIPPER  :
   case REXRIPPER     :
   case RISE          :
   case CN2           :
   case LERILS        :
   case PART          :r = *((Ruleset*) model);
                       return ruleset_complexity(r) + r.rulecount + 1; /*Complexity of conditions + classno of each rule + default class*/
   case DIVS          :mdivs = (Model_divsptr) model;
                       numparameters = mdivs->datacount; /*Classno of each ruleset*/
                       for (i = 0; i < mdivs->datacount; i++)
                         for (j = 0; j < mdivs->rulecounts[i]; j++)
                           numparameters += mdivs->conditioncounts[i][j]; /*Complexity of conditions*/
                       return numparameters;
   case RBF           :
   case RBFREG        :rbfparams = *((Rbf_parameterptr) parameters);
                       return rbfparams.input * rbfparams.hidden + rbfparams.hidden + rbfparams.output * (rbfparams.hidden + 1); /*m, s, w*/
   case MLPGENERIC    :
   case MLPGENERICREG :
   case DNC           :
   case DNCREG        :mlpparams = *((Mlpparameters*) parameters);
                       if (mlpparams.layernum != 0)
                        {
                         numparameters = (mlpparams.dimnum + 1) * mlpparams.hidden[0];
                         for (i = 0; i < mlpparams.layernum - 1; i++)
                           numparameters += (mlpparams.hidden[i] + 1) * mlpparams.hidden[i + 1]; /*weights from input to hiddens*/
                         numparameters += (mlpparams.hidden[i] + 1) * mlpparams.classnum; /*weights from last hidden to output*/
                        }
                       else
                         numparameters = (mlpparams.dimnum + 1) * mlpparams.classnum;
                       return numparameters;
   case SVMREGTREE    :
   case REGTREE       :
   case SOFTREGTREE   :rtrootnode = (Regressionnodeptr)model;
                       return complexity_of_regression_tree(rtrootnode);
   case REGRULE       :regr = *((Regressionruleset*) model);
                       return complexity_of_regression_ruleset(regr);
   case MULTILDT      :
   case OMNILDT       :
   case NBTREE        :
   case SOFTTREE      :
   case CART          :dtrootnode = (Decisionnodeptr)model;
                       return decisiontree_complexity_count(dtrootnode) + decisiontree_leaf_count(dtrootnode); /*Include class at the leaves*/
   case SVM           :nSV = 0;
                       msvm = (Svm_modelptr) model;
                       for (i = 0; i < msvm->nr_class; i++)
                         nSV += msvm->nSV[i];
                       return nSV * (current_dataset->multifeaturecount - 1);/*number of support vectors * number of features (realized)*/
   case SVMREG        :msvm = (Svm_modelptr) model;
                       nSV = msvm->l;
                       return nSV * (current_dataset->multifeaturecount - 1);/*number of support vectors * number of features (realized)*/
   case SIMPLEXSVM    :
   case SIMPLEXSVMREG :return number_of_support_vectors(model) * (current_dataset->multifeaturecount - 1);
   case HMM           :hmmarray = (Hmmptr*) model;
                       numparameters = 0;
                       for (i = 0; i < current_dataset->classno; i++)
                         numparameters += complexity_of_hmm(hmmarray[i]);
                       return numparameters;
  }
 return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rcx, %r15
movq %rdx, %rax
movq %rsi, %r14
movl $0x1, %ebx
leal -0x3e8(%rdi), %ecx
cmpl $0x24, %ecx
ja 0x4699
leaq 0xa09a1(%rip), %rdx     # 0xa5004
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
movl 0x10(%r14), %ebx
movq 0x20(%r14), %rax
movq %rax, 0x20(%rsp)
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
callq 0x7abde
addl %eax, %ebx
incl %ebx
jmp 0x4a2d
addl $0xfffff830, %edi       # imm = 0xFFFFF830
cmpl $0xe, %edi
ja 0x49c0
leaq 0xa09e9(%rip), %rcx     # 0xa5098
movslq (%rcx,%rdi,4), %rdx
addq %rcx, %rdx
jmpq *%rdx
movq %r14, %rdi
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x76644
movq %r14, %rdi
callq 0x1cb69
movl %eax, %ebp
movq %r14, %rdi
callq 0x1cc46
movl %eax, %ebx
addl %ebp, %ebx
jmp 0x4a2d
leaq 0x38(%rsp), %rbx
movl $0x90, %edx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x4310
movl 0x4(%rbx), %eax
movl 0x54(%rbx), %ecx
incl %eax
testl %ecx, %ecx
je 0x47fc
movl 0x80(%rsp), %ebx
imull %ebx, %eax
cmpl $0x2, %ecx
jl 0x4743
decl %ecx
xorl %edx, %edx
incl %ebx
movl 0x84(%rsp,%rdx,4), %esi
incq %rdx
imull %esi, %ebx
addl %ebx, %eax
movl %esi, %ebx
cmpq %rdx, %rcx
jne 0x4724
movl 0x80(%rsp,%rcx,4), %ebx
incl %ebx
imull 0x38(%rsp), %ebx
addl %eax, %ebx
jmp 0x4a2d
movq %r14, %rdi
callq 0x1cce7
movl %eax, %ebx
movq %r14, %rdi
callq 0x1cc46
leal (%rax,%rbx,2), %ebx
jmp 0x4a2d
movl 0x10(%r15), %ebx
imull 0x1c0(%r15), %ebx
jmp 0x4a2d
movq %r14, %rdi
callq 0x30309
movl %eax, %ebx
imull 0x1bc(%r15), %ebx
incl %ebx
jmp 0x4a2d
movq %r14, %rdi
callq 0x95ba3
jmp 0x4a21
movl 0x4(%rax), %ebx
movl 0x8(%rax), %ecx
incl %ecx
imull %ebx, %ecx
incl %ebx
imull (%rax), %ebx
jmp 0x48cb
leaq 0xa0f18(%rip), %rdi     # 0xa56d6
callq 0x54920
testl %eax, %eax
jle 0x49c0
movl %eax, %r13d
xorl %ebp, %ebp
xorl %ebx, %ebx
movq (%r14,%rbp,8), %r15
movq %r15, %rdi
callq 0x1cce7
movl %eax, %r12d
movq %r15, %rdi
callq 0x1cc46
addl %ebx, %eax
leal (%rax,%r12,2), %ebx
incq %rbp
cmpq %rbp, %r13
jne 0x47d2
jmp 0x4a2d
imull 0x38(%rsp), %eax
movl %eax, %ebx
jmp 0x4a2d
leaq 0xa0ed2(%rip), %rdi     # 0xa56e1
callq 0x54afc
movl 0x10(%r15), %ecx
testl %eax, %eax
jne 0x482b
leal -0x1(%rcx), %eax
imull %ecx, %eax
movl %eax, %ecx
shrl $0x1f, %ecx
addl %eax, %ecx
sarl %ecx
testl %ecx, %ecx
jle 0x49c0
movl %ecx, %r13d
xorl %ebp, %ebp
xorl %ebx, %ebx
movq (%r14,%rbp,8), %r15
movq %r15, %rdi
callq 0x1cce7
movl %eax, %r12d
movq %r15, %rdi
callq 0x1cc46
addl %ebx, %eax
leal (%rax,%r12,2), %ebx
incq %rbp
cmpq %rbp, %r13
jne 0x483a
jmp 0x4a2d
movslq 0x20(%r14), %rax
testq %rax, %rax
jle 0x4a16
movq 0x8(%r14), %rcx
xorl %edx, %edx
movl %eax, %ebx
movslq (%rcx,%rdx,4), %rsi
testq %rsi, %rsi
jle 0x4899
movq 0x18(%r14), %rdi
movq (%rdi,%rdx,8), %rdi
xorl %r8d, %r8d
addl (%rdi,%r8,4), %ebx
incq %r8
cmpq %r8, %rsi
jne 0x488d
incq %rdx
cmpq %rax, %rdx
jne 0x4879
jmp 0x4a2d
movl 0x1bc(%r15), %ebx
decl %ebx
jmp 0x49e3
movl (%r14), %ebx
leal -0x1(%rbx), %eax
movl 0x1c0(%r15), %ecx
decl %ecx
imull %eax, %ecx
imull 0x10(%r15), %ebx
addl %ecx, %ebx
jmp 0x4a2d
movslq 0x58(%r14), %rcx
testq %rcx, %rcx
jle 0x4a1f
movq 0x78(%r14), %rdx
xorl %esi, %esi
xorl %eax, %eax
addl (%rdx,%rsi,4), %eax
incq %rsi
cmpq %rsi, %rcx
jne 0x48e7
jmp 0x4a21
movl 0x10(%r15), %eax
movslq 0x1bc(%r15), %rdx
testq %rdx, %rdx
jle 0x4a16
leal 0x1(%rax), %ecx
imulq $0x340, %rdx, %rdx      # imm = 0x340
xorl %esi, %esi
movl %eax, %ebx
movl 0x30f08(%r15,%rsi), %edi
cmpl $0x2, %edi
je 0x492f
cmpl $0x1, %edi
je 0x4933
testl %edi, %edi
jne 0x4940
addl %ecx, %ebx
jmp 0x4940
movl 0x30f20(%r15,%rsi), %edi
imull %eax, %edi
addl %edi, %ebx
addq $0x340, %rsi            # imm = 0x340
cmpq %rsi, %rdx
jne 0x4919
jmp 0x4a2d
movl 0x1c0(%r15), %ebx
imull (%r14), %ebx
jmp 0x4a2d
movl 0x1c0(%r15), %ebx
jmp 0x4a2d
movl 0x1c0(%r15), %ebx
decl %ebx
imull 0x5c(%r14), %ebx
jmp 0x4a2d
cmpl $0x3, 0x1bc(%r15)
movl (%rax), %ebx
jl 0x4a1a
imull %ebx, %ebx
addl $0x5, %ebx
jmp 0x4a2d
cmpl $0x0, 0x10(%r15)
jle 0x49c0
xorl %r12d, %r12d
xorl %ebx, %ebx
movq (%r14,%r12,8), %rdi
callq 0x279ac
addl %eax, %ebx
incq %r12
movslq 0x10(%r15), %rax
cmpq %rax, %r12
jl 0x49a7
jmp 0x4a2d
xorl %ebx, %ebx
jmp 0x4a2d
movl $0x4, %ebx
jmp 0x4a2d
movl 0x1c0(%r15), %eax
leal -0x1(%rax), %ecx
imull %eax, %ecx
movl %ecx, %ebx
shrl $0x1f, %ebx
addl %ecx, %ebx
sarl %ebx
addl %eax, %ebx
imull 0x10(%r15), %ebx
jmp 0x4a2d
movq 0x30(%r14), %rax
movq %rax, 0x30(%rsp)
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups 0x20(%r14), %xmm2
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
callq 0x745e6
jmp 0x4a2f
movl %eax, %ebx
jmp 0x4a2d
addl $0x3, %ebx
jmp 0x4a2d
xorl %eax, %eax
movl 0x1c0(%r15), %ebx
decl %ebx
imull %eax, %ebx
movl %ebx, %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq