// File: lipiji[P]PG_DEEP/deep.cpp
// Function: DBN::pretrain(Dataset, Conf)
void DBN::pretrain(Dataset data, Conf conf)
{
    cout << "Layer-wise pre-training begin: " <<endl;

    char str[] = "./model/x_layer_";
    char x_l[256];
    vector<vector<double> > xlayer;

    double *rbm_input = NULL;
    double *pre_rbm_input = NULL;
    int pre_size;
    for(int l=0; l<n_layers; l++)
    {
        if(l > 0)
            data.reloadx(conf, x_l, xlayer);
        cout << "Layer: " << (l+1) << endl;
        for(int epoch=0; epoch<conf.epoch; epoch++)
        {
            if(epoch < 5)
                rbm_layers[l]->momentum = 0.5;
            else
                rbm_layers[l]->momentum = 0.9;

            double error = 0;
            for(int i=0; i<n_samples; i++)
            {
                if(l == 0)
                {
                    rbm_input = new double[n_features];
                    for(int f=0; f<n_features; f++)
                        rbm_input[f] = data.X[i][f];
                }
                else
                {
                    rbm_input = new double[hidden_layer_size[l-1]];
                    for(int f=0; f<hidden_layer_size[l-1]; f++)
                        rbm_input[f] = xlayer[i][f];

                }
                rbm_layers[l]->train(rbm_input, conf.learning_rate, conf.cd_k);
                delete[] rbm_input;
                error += rbm_layers[l]->error;
            }
            cout << "Layer: " << (l+1) << ", Epoch: " << epoch << ", Error: " << error << endl;
        }// end one layer

        //save the samples
        x_l[0]='\0';
        sprintf(x_l, "%s%d", str, (l+2));
        ofstream fout(x_l);
        if(l == 0)
            pre_size = n_features;
        else
            pre_size = hidden_layer_size[l-1];
        pre_rbm_input = new double[pre_size];
        for(int i=0; i<n_samples; i++)
        {
            for(int f=0; f<pre_size; f++)
            {
                if(l == 0)
                    pre_rbm_input[f] =  data.X[i][f];
                else
                    pre_rbm_input[f] =  xlayer[i][f];
            }
            rbm_input = new double[hidden_layer_size[l]];
            rbm_layers[l]->activate_hidden(pre_rbm_input, rbm_input, NULL, pre_size, hidden_layer_size[l]);
            for(int f=0; f<hidden_layer_size[l]; f++)
            {
                fout << rbm_input[f] << " ";
            }
            fout << endl;
            delete[] rbm_input;
        }
        delete[] pre_rbm_input;
        fout << flush;
        fout.close();
        if(l > 0)
            vector<vector<double> >().swap(xlayer);
    }//rbm layers end

    // logistic layer training
    data.reloadx(conf, x_l, xlayer);
    pre_size = lr_layer->n_features;
    rbm_input = new double[pre_size];

    for(int epoch=0; epoch<conf.epoch; epoch++)
    {
        for(int i=0; i<n_samples; i++)
        {
            int *train_y = new int[lr_layer->n_labels];
            for(int yi=0; yi<lr_layer->n_labels; yi++)
                train_y[yi] = 0;
            train_y[int(data.Y[i])] = 1;
            for(int f=0; f<pre_size; f++)
                rbm_input[f] = xlayer[i][f];

            //
            lr_layer->train(rbm_input, train_y, conf.learning_rate);
        }
        cout << "Layer: logistic layer, Epoch: " << epoch  << endl;
    }
    delete[] rbm_input;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x600, %rsp            # imm = 0x600
movq %rsi, -0x540(%rbp)
movq %rdx, -0x538(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x530(%rbp)
movq 0x7fa9(%rip), %rdi      # 0xefd0
leaq 0x412c(%rip), %rsi      # 0xb15a
callq 0x2210
movq %rax, %rdi
movq 0x7f83(%rip), %rsi      # 0xefc0
callq 0x2240
movq 0x41b7(%rip), %rax      # 0xb200
movq %rax, -0x30(%rbp)
movq 0x41b4(%rip), %rax      # 0xb208
movq %rax, -0x28(%rbp)
movb 0x41b2(%rip), %al       # 0xb210
movb %al, -0x20(%rbp)
leaq -0x148(%rbp), %rdi
callq 0x8ed0
movq $0x0, -0x150(%rbp)
movq $0x0, -0x158(%rbp)
movl $0x0, -0x160(%rbp)
movq -0x530(%rbp), %rcx
movl -0x160(%rbp), %eax
cmpl 0x8(%rcx), %eax
jge 0x78af
cmpl $0x0, -0x160(%rbp)
jle 0x7130
movq -0x538(%rbp), %rsi
leaq -0x210(%rbp), %rdi
callq 0x3170
jmp 0x70c5
movq -0x540(%rbp), %rdi
leaq -0x210(%rbp), %rsi
leaq -0x130(%rbp), %rdx
leaq -0x148(%rbp), %rcx
callq 0x5460
jmp 0x70e8
leaq -0x210(%rbp), %rdi
callq 0x4cb0
jmp 0x7130
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x218(%rbp)
movl %eax, -0x21c(%rbp)
jmp 0x7ba7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x218(%rbp)
movl %eax, -0x21c(%rbp)
leaq -0x210(%rbp), %rdi
callq 0x4cb0
jmp 0x7ba7
movq 0x7e99(%rip), %rdi      # 0xefd0
leaq 0x403c(%rip), %rsi      # 0xb17a
callq 0x2210
movq %rax, -0x548(%rbp)
jmp 0x714c
movq -0x548(%rbp), %rdi
movl -0x160(%rbp), %esi
incl %esi
callq 0x2380
movq %rax, -0x550(%rbp)
jmp 0x7169
movq -0x550(%rbp), %rdi
movq 0x7e49(%rip), %rsi      # 0xefc0
callq 0x2240
jmp 0x717e
movl $0x0, -0x220(%rbp)
movq -0x538(%rbp), %rcx
movl -0x220(%rbp), %eax
cmpl 0x80(%rcx), %eax
jge 0x7505
cmpl $0x5, -0x220(%rbp)
jge 0x71cf
movq -0x530(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x160(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsd 0x3f10(%rip), %xmm0     # 0xb0d8
movsd %xmm0, 0x38(%rax)
jmp 0x71f2
movq -0x530(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x160(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsd 0x3ef3(%rip), %xmm0     # 0xb0e0
movsd %xmm0, 0x38(%rax)
xorps %xmm0, %xmm0
movsd %xmm0, -0x228(%rbp)
movl $0x0, -0x22c(%rbp)
movq -0x530(%rbp), %rcx
movl -0x22c(%rbp), %eax
cmpl (%rcx), %eax
jge 0x7431
cmpl $0x0, -0x160(%rbp)
jne 0x72d5
movq -0x530(%rbp), %rax
movslq 0x4(%rax), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x558(%rbp)
jmp 0x7258
movq -0x558(%rbp), %rax
movq %rax, -0x150(%rbp)
movl $0x0, -0x230(%rbp)
movq -0x530(%rbp), %rcx
movl -0x230(%rbp), %eax
cmpl 0x4(%rcx), %eax
jge 0x72d0
movq -0x540(%rbp), %rdi
addq $0x8, %rdi
movslq -0x22c(%rbp), %rsi
callq 0x32e0
movq %rax, %rdi
movslq -0x230(%rbp), %rsi
callq 0x3300
movsd (%rax), %xmm0
movq -0x150(%rbp), %rax
movslq -0x230(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x230(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x230(%rbp)
jmp 0x7270
jmp 0x7399
movq -0x530(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x160(%rbp), %ecx
decl %ecx
movslq %ecx, %rcx
movslq (%rax,%rcx,4), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x560(%rbp)
jmp 0x7313
movq -0x560(%rbp), %rax
movq %rax, -0x150(%rbp)
movl $0x0, -0x234(%rbp)
movq -0x530(%rbp), %rcx
movl -0x234(%rbp), %eax
movq 0x10(%rcx), %rcx
movl -0x160(%rbp), %edx
subl $0x1, %edx
movslq %edx, %rdx
cmpl (%rcx,%rdx,4), %eax
jge 0x7397
movslq -0x22c(%rbp), %rsi
leaq -0x148(%rbp), %rdi
callq 0x32e0
movq %rax, %rdi
movslq -0x234(%rbp), %rsi
callq 0x3300
movsd (%rax), %xmm0
movq -0x150(%rbp), %rax
movslq -0x234(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x234(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x234(%rbp)
jmp 0x732b
jmp 0x7399
movq -0x538(%rbp), %rax
movq -0x530(%rbp), %rcx
movq 0x28(%rcx), %rcx
movslq -0x160(%rbp), %rdx
movq (%rcx,%rdx,8), %rdi
movq -0x150(%rbp), %rsi
movsd 0x98(%rax), %xmm0
movl 0x90(%rax), %edx
callq 0x6070
jmp 0x73d2
movq -0x150(%rbp), %rax
movq %rax, -0x568(%rbp)
cmpq $0x0, %rax
je 0x73f2
movq -0x568(%rbp), %rdi
callq 0x22e0
movq -0x530(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x160(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsd 0x28(%rax), %xmm0
addsd -0x228(%rbp), %xmm0
movsd %xmm0, -0x228(%rbp)
movl -0x22c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x22c(%rbp)
jmp 0x7207
movq 0x7b98(%rip), %rdi      # 0xefd0
leaq 0x3d3b(%rip), %rsi      # 0xb17a
callq 0x2210
movq %rax, -0x570(%rbp)
jmp 0x744d
movq -0x570(%rbp), %rdi
movl -0x160(%rbp), %esi
incl %esi
callq 0x2380
movq %rax, -0x578(%rbp)
jmp 0x746a
movq -0x578(%rbp), %rdi
leaq 0x3d29(%rip), %rsi      # 0xb1a1
callq 0x2210
movq %rax, -0x580(%rbp)
jmp 0x7486
movq -0x580(%rbp), %rdi
movl -0x220(%rbp), %esi
callq 0x2380
movq %rax, -0x588(%rbp)
jmp 0x74a1
movq -0x588(%rbp), %rdi
leaq 0x3cd3(%rip), %rsi      # 0xb182
callq 0x2210
movq %rax, -0x590(%rbp)
jmp 0x74bd
movq -0x590(%rbp), %rdi
movsd -0x228(%rbp), %xmm0
callq 0x23f0
movq %rax, -0x598(%rbp)
jmp 0x74da
movq -0x598(%rbp), %rdi
movq 0x7ad8(%rip), %rsi      # 0xefc0
callq 0x2240
jmp 0x74ef
jmp 0x74f1
movl -0x220(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x220(%rbp)
jmp 0x7188
movb $0x0, -0x130(%rbp)
movl -0x160(%rbp), %ecx
addl $0x2, %ecx
leaq 0x3b22(%rip), %rsi      # 0xb03e
xorl %eax, %eax
leaq -0x130(%rbp), %rdi
movq %rdi, -0x5a0(%rbp)
leaq -0x30(%rbp), %rdx
callq 0x2060
movq -0x5a0(%rbp), %rsi
leaq -0x438(%rbp), %rdi
movl $0x10, %edx
callq 0x2270
jmp 0x754f
cmpl $0x0, -0x160(%rbp)
jne 0x756a
movq -0x530(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x15c(%rbp)
jmp 0x758a
movq -0x530(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x160(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x15c(%rbp)
movslq -0x15c(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x5a8(%rbp)
jmp 0x75b5
movq -0x5a8(%rbp), %rax
movq %rax, -0x158(%rbp)
movl $0x0, -0x43c(%rbp)
movq -0x530(%rbp), %rcx
movl -0x43c(%rbp), %eax
cmpl (%rcx), %eax
jge 0x7805
movl $0x0, -0x440(%rbp)
movl -0x440(%rbp), %eax
cmpl -0x15c(%rbp), %eax
jge 0x76b8
cmpl $0x0, -0x160(%rbp)
jne 0x7669
movq -0x540(%rbp), %rdi
addq $0x8, %rdi
movslq -0x43c(%rbp), %rsi
callq 0x32e0
movq %rax, %rdi
movslq -0x440(%rbp), %rsi
callq 0x3300
movsd (%rax), %xmm0
movq -0x158(%rbp), %rax
movslq -0x440(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
jmp 0x76a2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x218(%rbp)
movl %eax, -0x21c(%rbp)
leaq -0x438(%rbp), %rdi
callq 0x2330
jmp 0x7ba7
movslq -0x43c(%rbp), %rsi
leaq -0x148(%rbp), %rdi
callq 0x32e0
movq %rax, %rdi
movslq -0x440(%rbp), %rsi
callq 0x3300
movsd (%rax), %xmm0
movq -0x158(%rbp), %rax
movslq -0x440(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
jmp 0x76a4
movl -0x440(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x440(%rbp)
jmp 0x75ec
movq -0x530(%rbp), %rax
movq 0x10(%rax), %rax
movslq -0x160(%rbp), %rcx
movslq (%rax,%rcx,4), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x5b0(%rbp)
jmp 0x76f2
movq -0x530(%rbp), %rax
movq -0x5b0(%rbp), %rcx
movq %rcx, -0x150(%rbp)
movq 0x28(%rax), %rcx
movslq -0x160(%rbp), %rdx
movq (%rcx,%rdx,8), %rdi
movq -0x158(%rbp), %rsi
movq -0x150(%rbp), %rdx
movl -0x15c(%rbp), %r8d
movq 0x10(%rax), %rax
movslq -0x160(%rbp), %rcx
movl (%rax,%rcx,4), %r9d
xorl %eax, %eax
movl %eax, %ecx
callq 0x5e60
movl $0x0, -0x444(%rbp)
movq -0x530(%rbp), %rcx
movl -0x444(%rbp), %eax
movq 0x10(%rcx), %rcx
movslq -0x160(%rbp), %rdx
cmpl (%rcx,%rdx,4), %eax
jge 0x77ba
movq -0x150(%rbp), %rax
movslq -0x444(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
leaq -0x438(%rbp), %rdi
callq 0x23f0
movq %rax, -0x5b8(%rbp)
jmp 0x7792
movq -0x5b8(%rbp), %rdi
leaq 0x3a09(%rip), %rsi      # 0xb1a9
callq 0x2210
jmp 0x77a7
jmp 0x77a9
movl -0x444(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x444(%rbp)
jmp 0x774d
movq 0x77ff(%rip), %rsi      # 0xefc0
leaq -0x438(%rbp), %rdi
callq 0x2240
jmp 0x77cf
movq -0x150(%rbp), %rax
movq %rax, -0x5c0(%rbp)
cmpq $0x0, %rax
je 0x77ef
movq -0x5c0(%rbp), %rdi
callq 0x22e0
jmp 0x77f1
movl -0x43c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x43c(%rbp)
jmp 0x75cd
movq -0x158(%rbp), %rax
movq %rax, -0x5c8(%rbp)
cmpq $0x0, %rax
je 0x7825
movq -0x5c8(%rbp), %rdi
callq 0x22e0
movq 0x77ac(%rip), %rsi      # 0xefd8
leaq -0x438(%rbp), %rdi
callq 0x2240
jmp 0x783a
leaq -0x438(%rbp), %rdi
callq 0x2310
jmp 0x7848
cmpl $0x0, -0x160(%rbp)
jle 0x788f
leaq -0x460(%rbp), %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0x2130
leaq -0x460(%rbp), %rdi
callq 0x8ed0
leaq -0x460(%rbp), %rdi
leaq -0x148(%rbp), %rsi
callq 0x9010
leaq -0x460(%rbp), %rdi
callq 0x3500
leaq -0x438(%rbp), %rdi
callq 0x2330
movl -0x160(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x160(%rbp)
jmp 0x708d
movq -0x538(%rbp), %rsi
leaq -0x510(%rbp), %rdi
callq 0x3170
jmp 0x78c4
movq -0x540(%rbp), %rdi
leaq -0x510(%rbp), %rsi
leaq -0x130(%rbp), %rdx
leaq -0x148(%rbp), %rcx
callq 0x5460
jmp 0x78e7
leaq -0x510(%rbp), %rdi
callq 0x4cb0
movq -0x530(%rbp), %rax
movq 0x30(%rax), %rax
movl 0x4(%rax), %eax
movl %eax, -0x15c(%rbp)
movslq -0x15c(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x5d0(%rbp)
jmp 0x7932
movq -0x5d0(%rbp), %rax
movq %rax, -0x150(%rbp)
movl $0x0, -0x514(%rbp)
movq -0x538(%rbp), %rcx
movl -0x514(%rbp), %eax
cmpl 0x80(%rcx), %eax
jge 0x7b72
movl $0x0, -0x518(%rbp)
movq -0x530(%rbp), %rcx
movl -0x518(%rbp), %eax
cmpl (%rcx), %eax
jge 0x7b10
movq -0x530(%rbp), %rax
movq 0x30(%rax), %rax
movslq 0x8(%rax), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x5d8(%rbp)
jmp 0x79b5
movq -0x5d8(%rbp), %rax
movq %rax, -0x520(%rbp)
movl $0x0, -0x524(%rbp)
movq -0x530(%rbp), %rcx
movl -0x524(%rbp), %eax
movq 0x30(%rcx), %rcx
cmpl 0x8(%rcx), %eax
jge 0x7a2c
movq -0x520(%rbp), %rax
movslq -0x524(%rbp), %rcx
movl $0x0, (%rax,%rcx,4)
movl -0x524(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x524(%rbp)
jmp 0x79cd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x218(%rbp)
movl %eax, -0x21c(%rbp)
leaq -0x510(%rbp), %rdi
callq 0x4cb0
jmp 0x7ba7
movq -0x540(%rbp), %rdi
movq -0x520(%rbp), %rax
movq %rax, -0x5e0(%rbp)
addq $0x20, %rdi
movslq -0x518(%rbp), %rsi
callq 0x3300
movq %rax, %rcx
movq -0x5e0(%rbp), %rax
cvttsd2si (%rcx), %ecx
movslq %ecx, %rcx
movl $0x1, (%rax,%rcx,4)
movl $0x0, -0x528(%rbp)
movl -0x528(%rbp), %eax
cmpl -0x15c(%rbp), %eax
jge 0x7acb
movslq -0x518(%rbp), %rsi
leaq -0x148(%rbp), %rdi
callq 0x32e0
movq %rax, %rdi
movslq -0x528(%rbp), %rsi
callq 0x3300
movsd (%rax), %xmm0
movq -0x150(%rbp), %rax
movslq -0x528(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x528(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x528(%rbp)
jmp 0x7a73
movq -0x538(%rbp), %rax
movq -0x530(%rbp), %rcx
movq 0x30(%rcx), %rdi
movq -0x150(%rbp), %rsi
movq -0x520(%rbp), %rdx
movsd 0x98(%rax), %xmm0
callq 0x68f0
jmp 0x7afa
jmp 0x7afc
movl -0x518(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x518(%rbp)
jmp 0x796d
movq 0x74b9(%rip), %rdi      # 0xefd0
leaq 0x366e(%rip), %rsi      # 0xb18c
callq 0x2210
movq %rax, -0x5e8(%rbp)
jmp 0x7b2c
movq -0x5e8(%rbp), %rdi
movl -0x514(%rbp), %esi
callq 0x2380
movq %rax, -0x5f0(%rbp)
jmp 0x7b47
movq -0x5f0(%rbp), %rdi
movq 0x746b(%rip), %rsi      # 0xefc0
callq 0x2240
jmp 0x7b5c
jmp 0x7b5e
movl -0x514(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x514(%rbp)
jmp 0x794a
movq -0x150(%rbp), %rax
movq %rax, -0x5f8(%rbp)
cmpq $0x0, %rax
je 0x7b92
movq -0x5f8(%rbp), %rdi
callq 0x22e0
leaq -0x148(%rbp), %rdi
callq 0x3500
addq $0x600, %rsp            # imm = 0x600
popq %rbp
retq
leaq -0x148(%rbp), %rdi
callq 0x3500
movq -0x218(%rbp), %rdi
callq 0x23a0
nop