// File: wkohlenberg[P]simple_NN/src/main.cpp
// Function: main
int main()
{
  // Topology
  vector<unsigned> topology;
  topology.push_back(INPUT);
  topology.push_back(HIDDEN);
  topology.push_back(OUTPUT);

  // Read training data file
  TrainData trainData("input/xor_train_data.txt");

  // Open log file
  LogData log("output/log.txt");

  // Create the neural net
  Net NN(topology);

  vector<double> inputVals;   // Input values
  vector<double> targetVals;  // Target values
  vector<double> outputVals;  // Output values

  unsigned int train_num = 1;
  for (unsigned int epoch_num = 1; epoch_num <= EPOCH; epoch_num++)
  {
    // Train the neural net by training data
    while (!trainData.isEof())
    {
      // Last row of file is empty
      if (trainData.readInput(inputVals) != topology[0])
      {
        break;
      }

      trainData.readTarget(targetVals);
      cout << endl << "Epoch: " << epoch_num << "; Train num: " << train_num << endl;
      cout << "in: " << showVectorValues(inputVals) << endl;
      cout << "out: " << showVectorValues(targetVals) << endl;

      // Feed forward
      NN.feedForward(inputVals);
      NN.getOutputValLayer(outputVals);
      cout << "res: " << showVectorValues(outputVals) << endl;

      // Backpropogation
      NN.backPropagation(targetVals);
      cout << "Total error is " << NN.getAvgError() << endl;
      log.write(NN.getAvgError());

      train_num++;
    }

    train_num = 1;
    trainData.toBeginOfFile();
  }

  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x650, %rsp            # imm = 0x650
movl $0x0, -0x4(%rbp)
leaq -0x20(%rbp), %rdi
movq %rdi, -0x5c0(%rbp)
callq 0x58a0
movq -0x5c0(%rbp), %rdi
movl $0x2, -0x24(%rbp)
leaq -0x24(%rbp), %rsi
callq 0x58c0
jmp 0x49ab
movl $0x4, -0x38(%rbp)
leaq -0x20(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x58c0
jmp 0x49c1
movl $0x1, -0x3c(%rbp)
leaq -0x20(%rbp), %rdi
leaq -0x3c(%rbp), %rsi
callq 0x58c0
jmp 0x49d7
leaq -0x269(%rbp), %rdi
movq %rdi, -0x5c8(%rbp)
callq 0x33b0
movq -0x5c8(%rbp), %rdx
leaq 0x967f(%rip), %rsi      # 0xe077
leaq -0x268(%rbp), %rdi
callq 0x58f0
jmp 0x4a06
leaq -0x248(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0x3700
jmp 0x4a1b
leaq -0x268(%rbp), %rdi
callq 0x3100
leaq -0x269(%rbp), %rdi
callq 0x3230
leaq -0x491(%rbp), %rdi
movq %rdi, -0x5d0(%rbp)
callq 0x33b0
movq -0x5d0(%rbp), %rdx
leaq 0x963c(%rip), %rsi      # 0xe090
leaq -0x490(%rbp), %rdi
callq 0x58f0
jmp 0x4a62
leaq -0x470(%rbp), %rdi
leaq -0x490(%rbp), %rsi
callq 0x35b0
jmp 0x4a77
leaq -0x490(%rbp), %rdi
callq 0x3100
leaq -0x491(%rbp), %rdi
callq 0x3230
leaq -0x4c0(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x4650
jmp 0x4aa1
leaq -0x4d8(%rbp), %rdi
callq 0x59a0
leaq -0x4f0(%rbp), %rdi
callq 0x59a0
leaq -0x508(%rbp), %rdi
callq 0x59a0
movl $0x1, -0x50c(%rbp)
movl $0x1, -0x510(%rbp)
cmpl $0x4, -0x510(%rbp)
ja 0x5003
jmp 0x4ae8
leaq -0x248(%rbp), %rdi
callq 0x59c0
movb %al, -0x5d1(%rbp)
jmp 0x4afc
movb -0x5d1(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x4b0d
jmp 0x4fd5
leaq -0x248(%rbp), %rdi
leaq -0x4d8(%rbp), %rsi
callq 0x3810
movl %eax, -0x5d8(%rbp)
jmp 0x4b28
leaq -0x20(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x59f0
movq %rax, %rcx
movl -0x5d8(%rbp), %eax
cmpl (%rcx), %eax
je 0x4bec
jmp 0x4fd5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x50af
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x4b82
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x268(%rbp), %rdi
callq 0x3100
leaq -0x269(%rbp), %rdi
callq 0x3230
jmp 0x50af
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x4bb9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x490(%rbp), %rdi
callq 0x3100
leaq -0x491(%rbp), %rdi
callq 0x3230
jmp 0x50a3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x5097
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x5067
leaq -0x248(%rbp), %rdi
leaq -0x4f0(%rbp), %rsi
callq 0x3920
jmp 0x4c01
movq 0x103d0(%rip), %rdi     # 0x14fd8
movq 0x103b1(%rip), %rsi     # 0x14fc0
callq 0x3210
movq %rax, -0x5e0(%rbp)
jmp 0x4c1d
movq -0x5e0(%rbp), %rdi
leaq 0x9474(%rip), %rsi      # 0xe09f
callq 0x31e0
movq %rax, -0x5e8(%rbp)
jmp 0x4c39
movq -0x5e8(%rbp), %rdi
movl -0x510(%rbp), %esi
callq 0x32a0
movq %rax, -0x5f0(%rbp)
jmp 0x4c54
movq -0x5f0(%rbp), %rdi
leaq 0x9445(%rip), %rsi      # 0xe0a7
callq 0x31e0
movq %rax, -0x5f8(%rbp)
jmp 0x4c70
movq -0x5f8(%rbp), %rdi
movl -0x50c(%rbp), %esi
callq 0x32a0
movq %rax, -0x600(%rbp)
jmp 0x4c8b
movq -0x600(%rbp), %rdi
movq 0x10327(%rip), %rsi     # 0x14fc0
callq 0x3210
jmp 0x4ca0
movq 0x10331(%rip), %rdi     # 0x14fd8
leaq 0x9407(%rip), %rsi      # 0xe0b5
callq 0x31e0
movq %rax, -0x608(%rbp)
jmp 0x4cbc
leaq -0x548(%rbp), %rdi
leaq -0x4d8(%rbp), %rsi
callq 0x5a10
jmp 0x4cd1
leaq -0x530(%rbp), %rdi
leaq -0x548(%rbp), %rsi
callq 0x4870
jmp 0x4ce6
movq -0x608(%rbp), %rdi
leaq -0x530(%rbp), %rsi
callq 0x31c0
movq %rax, -0x610(%rbp)
jmp 0x4d02
movq -0x610(%rbp), %rdi
movq 0x102b0(%rip), %rsi     # 0x14fc0
callq 0x3210
jmp 0x4d17
leaq -0x530(%rbp), %rdi
callq 0x3100
leaq -0x548(%rbp), %rdi
callq 0x5b00
movq 0x102a2(%rip), %rdi     # 0x14fd8
leaq 0x937d(%rip), %rsi      # 0xe0ba
callq 0x31e0
movq %rax, -0x618(%rbp)
jmp 0x4d4b
leaq -0x580(%rbp), %rdi
leaq -0x4f0(%rbp), %rsi
callq 0x5a10
jmp 0x4d60
leaq -0x568(%rbp), %rdi
leaq -0x580(%rbp), %rsi
callq 0x4870
jmp 0x4d75
movq -0x618(%rbp), %rdi
leaq -0x568(%rbp), %rsi
callq 0x31c0
movq %rax, -0x620(%rbp)
jmp 0x4d91
movq -0x620(%rbp), %rdi
movq 0x10221(%rip), %rsi     # 0x14fc0
callq 0x3210
jmp 0x4da6
leaq -0x568(%rbp), %rdi
callq 0x3100
leaq -0x580(%rbp), %rdi
callq 0x5b00
leaq -0x4c0(%rbp), %rdi
leaq -0x4d8(%rbp), %rsi
callq 0x41e0
jmp 0x4dd3
leaq -0x4c0(%rbp), %rdi
leaq -0x508(%rbp), %rsi
callq 0x4140
jmp 0x4de8
movq 0x101e9(%rip), %rdi     # 0x14fd8
leaq 0x92ca(%rip), %rsi      # 0xe0c0
callq 0x31e0
movq %rax, -0x628(%rbp)
jmp 0x4e04
leaq -0x5b8(%rbp), %rdi
leaq -0x508(%rbp), %rsi
callq 0x5a10
jmp 0x4e19
leaq -0x5a0(%rbp), %rdi
leaq -0x5b8(%rbp), %rsi
callq 0x4870
jmp 0x4e2e
movq -0x628(%rbp), %rdi
leaq -0x5a0(%rbp), %rsi
callq 0x31c0
movq %rax, -0x630(%rbp)
jmp 0x4e4a
movq -0x630(%rbp), %rdi
movq 0x10168(%rip), %rsi     # 0x14fc0
callq 0x3210
jmp 0x4e5f
leaq -0x5a0(%rbp), %rdi
callq 0x3100
leaq -0x5b8(%rbp), %rdi
callq 0x5b00
leaq -0x4c0(%rbp), %rdi
leaq -0x4f0(%rbp), %rsi
callq 0x4330
jmp 0x4e8c
movq 0x10145(%rip), %rdi     # 0x14fd8
leaq 0x922c(%rip), %rsi      # 0xe0c6
callq 0x31e0
movq %rax, -0x638(%rbp)
jmp 0x4ea8
leaq -0x4c0(%rbp), %rdi
callq 0x5b60
movsd %xmm0, -0x640(%rbp)
jmp 0x4ebe
movsd -0x640(%rbp), %xmm0
movq -0x638(%rbp), %rdi
callq 0x33f0
movq %rax, -0x648(%rbp)
jmp 0x4edb
movq -0x648(%rbp), %rdi
movq 0x100d7(%rip), %rsi     # 0x14fc0
callq 0x3210
jmp 0x4ef0
leaq -0x4c0(%rbp), %rdi
callq 0x5b60
movsd %xmm0, -0x650(%rbp)
jmp 0x4f06
movsd -0x650(%rbp), %xmm0
leaq -0x470(%rbp), %rdi
callq 0x36c0
jmp 0x4f1c
movl -0x50c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50c(%rbp)
jmp 0x4ae8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x4f56
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x530(%rbp), %rdi
callq 0x3100
leaq -0x548(%rbp), %rdi
callq 0x5b00
jmp 0x5067
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x4f8d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x568(%rbp), %rdi
callq 0x3100
leaq -0x580(%rbp), %rdi
callq 0x5b00
jmp 0x5067
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x4fc4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x5a0(%rbp), %rdi
callq 0x3100
leaq -0x5b8(%rbp), %rdi
callq 0x5b00
jmp 0x5067
movl $0x1, -0x50c(%rbp)
leaq -0x248(%rbp), %rdi
callq 0x38e0
jmp 0x4fed
jmp 0x4fef
movl -0x510(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x510(%rbp)
jmp 0x4ad9
movl $0x0, -0x4(%rbp)
leaq -0x508(%rbp), %rdi
callq 0x5b00
leaq -0x4f0(%rbp), %rdi
callq 0x5b00
leaq -0x4d8(%rbp), %rdi
callq 0x5b00
leaq -0x4c0(%rbp), %rdi
callq 0x5b80
leaq -0x470(%rbp), %rdi
callq 0x3680
leaq -0x248(%rbp), %rdi
callq 0x37d0
leaq -0x20(%rbp), %rdi
callq 0x5ba0
movl -0x4(%rbp), %eax
addq $0x650, %rsp            # imm = 0x650
popq %rbp
retq
leaq -0x508(%rbp), %rdi
callq 0x5b00
leaq -0x4f0(%rbp), %rdi
callq 0x5b00
leaq -0x4d8(%rbp), %rdi
callq 0x5b00
leaq -0x4c0(%rbp), %rdi
callq 0x5b80
leaq -0x470(%rbp), %rdi
callq 0x3680
leaq -0x248(%rbp), %rdi
callq 0x37d0
leaq -0x20(%rbp), %rdi
callq 0x5ba0
movq -0x30(%rbp), %rdi
callq 0x33a0
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)