// File: /workspace/github_c_makefile_star2_O2/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
pushq $0x1
popq %rbx
leal -0x3e8(%rdi), %ecx
cmpl $0x24, %ecx
ja 0x46a3
leaq 0x90997(%rip), %rdx     # 0x95004
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 0x70685
addl %eax, %ebx
incl %ebx
jmp 0x49f5
addl $0xfffff830, %edi       # imm = 0xFFFFF830
cmpl $0xe, %edi
ja 0x49d5
leaq 0x909df(%rip), %rcx     # 0x95098
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 0x6c5c9
movq %r14, %rdi
callq 0x1a75b
movl %eax, %ebp
movq %r14, %rdi
callq 0x1a834
movl %eax, %ebx
addl %ebp, %ebx
jmp 0x49f5
leaq 0x38(%rsp), %rbx
movl $0x90, %edx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x4310
movl 0x4(%rbx), %eax
movl 0x54(%rbx), %esi
incl %eax
testl %esi, %esi
je 0x4817
movl 0x80(%rsp), %ecx
imull %ecx, %eax
cmpl $0x2, %esi
pushq $0x1
popq %rdx
cmovgel %esi, %edx
decl %edx
xorl %esi, %esi
cmpq %rsi, %rdx
je 0x4766
incl %ecx
movl 0x84(%rsp,%rsi,4), %edi
incq %rsi
imull %edi, %ecx
addl %ecx, %eax
movl %edi, %ecx
jmp 0x4732
movq %r14, %rdi
callq 0x1a8d0
movl %eax, %ebx
movq %r14, %rdi
callq 0x1a834
leal (%rax,%rbx,2), %ebx
jmp 0x49f5
movl 0x80(%rsp,%rdx,4), %ebx
incl %ebx
imull 0x38(%rsp), %ebx
addl %eax, %ebx
jmp 0x49f5
movl 0x10(%r15), %ebx
imull 0x1c0(%r15), %ebx
jmp 0x49f5
movq %r14, %rdi
callq 0x2c3cc
movl %eax, %ebx
imull 0x1bc(%r15), %ebx
incl %ebx
jmp 0x49f5
movq %r14, %rdi
callq 0x8758c
movl 0x1c0(%r15), %ebx
decl %ebx
imull %eax, %ebx
jmp 0x49f5
movl 0x4(%rax), %ebx
movl 0x8(%rax), %ecx
incl %ecx
imull %ebx, %ecx
incl %ebx
imull (%rax), %ebx
jmp 0x48e7
leaq 0x90efc(%rip), %rdi     # 0x956d6
callq 0x4cd35
movl %eax, %r15d
xorl %ebp, %ebp
testl %eax, %eax
cmovlel %ebp, %r15d
xorl %ebx, %ebx
cmpq %rbp, %r15
je 0x49f5
movq (%r14,%rbp,8), %r12
movq %r12, %rdi
callq 0x1a8d0
movl %eax, %r13d
movq %r12, %rdi
callq 0x1a834
addl %ebx, %eax
leal (%rax,%r13,2), %ebx
incq %rbp
jmp 0x47ec
imull 0x38(%rsp), %eax
movl %eax, %ebx
jmp 0x49f5
leaq 0x90eb7(%rip), %rdi     # 0x956e1
callq 0x4cf11
movl 0x10(%r15), %r15d
testl %eax, %eax
jne 0x4848
leal -0x1(%r15), %eax
imull %r15d, %eax
pushq $0x2
popq %rcx
cltd
idivl %ecx
movl %eax, %r15d
xorl %ebp, %ebp
testl %r15d, %r15d
cmovlel %ebp, %r15d
xorl %ebx, %ebx
cmpq %rbp, %r15
je 0x49f5
movq (%r14,%rbp,8), %r12
movq %r12, %rdi
callq 0x1a8d0
movl %eax, %r13d
movq %r12, %rdi
callq 0x1a834
addl %ebx, %eax
leal (%rax,%r13,2), %ebx
incq %rbp
jmp 0x4853
movl 0x20(%r14), %ebx
xorl %eax, %eax
testl %ebx, %ebx
movl $0x0, %ecx
cmovgl %ebx, %ecx
xorl %edx, %edx
cmpq %rcx, %rdx
je 0x49f5
movq 0x8(%r14), %rsi
movl (%rsi,%rdx,4), %esi
testl %esi, %esi
cmovlel %eax, %esi
xorl %edi, %edi
cmpq %rdi, %rsi
je 0x48bd
movq 0x18(%r14), %r8
movq (%r8,%rdx,8), %r8
addl (%r8,%rdi,4), %ebx
incq %rdi
jmp 0x48a7
incq %rdx
jmp 0x4890
movl 0x1bc(%r15), %ebx
decl %ebx
jmp 0x49f0
movl (%r14), %ebx
leal -0x1(%rbx), %eax
movl 0x1c0(%r15), %ecx
decl %ecx
imull %eax, %ecx
imull 0x10(%r15), %ebx
addl %ecx, %ebx
jmp 0x49f5
movl 0x58(%r14), %eax
xorl %ecx, %ecx
testl %eax, %eax
cmovlel %ecx, %eax
xorl %edx, %edx
cmpq %rcx, %rax
je 0x490c
movq 0x78(%r14), %rsi
addl (%rsi,%rcx,4), %edx
incq %rcx
jmp 0x48fb
movl 0x1c0(%r15), %ebx
decl %ebx
imull %edx, %ebx
jmp 0x49f5
movl 0x10(%r15), %eax
movl 0x1bc(%r15), %esi
leal 0x1(%rax), %ecx
xorl %edx, %edx
testl %esi, %esi
cmovlel %edx, %esi
imulq $0x340, %rsi, %rsi      # imm = 0x340
movl %eax, %ebx
cmpq %rdx, %rsi
je 0x49f5
movl 0x30f08(%r15,%rdx), %edi
cmpl $0x2, %edi
je 0x495a
cmpl $0x1, %edi
je 0x495e
testl %edi, %edi
jne 0x496b
addl %ecx, %ebx
jmp 0x496b
movl 0x30f20(%r15,%rdx), %edi
imull %eax, %edi
addl %edi, %ebx
addq $0x340, %rdx            # imm = 0x340
jmp 0x493b
movl 0x1c0(%r15), %ebx
imull (%r14), %ebx
jmp 0x49f5
movl 0x1c0(%r15), %ebx
jmp 0x49f5
movl 0x1c0(%r15), %ebx
decl %ebx
imull 0x5c(%r14), %ebx
jmp 0x49f5
cmpl $0x3, 0x1bc(%r15)
movl (%rax), %ebx
jl 0x4a35
imull %ebx, %ebx
addl $0x5, %ebx
jmp 0x49f5
xorl %r12d, %r12d
xorl %ebx, %ebx
movslq 0x10(%r15), %rax
cmpq %rax, %r12
jge 0x49f5
movq (%r14,%r12,8), %rdi
callq 0x244b8
addl %eax, %ebx
incq %r12
jmp 0x49b7
pushq $0x4
popq %rbx
jmp 0x49f5
xorl %ebx, %ebx
jmp 0x49f5
movl 0x1c0(%r15), %ecx
leal -0x1(%rcx), %eax
imull %ecx, %eax
pushq $0x2
popq %rsi
cltd
idivl %esi
movl %eax, %ebx
addl %ecx, %ebx
imull 0x10(%r15), %ebx
movl %ebx, %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
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 0x6a90d
jmp 0x49f7
addl $0x3, %ebx
jmp 0x49f5