// File: leonn[P]neuralNet/source/net.cpp
// Function: Net::backPropagation(std::vector<double, std::allocator<double>> const&, long double const&, long double const&)
void Net::backPropagation(const vector<double> &targetValues,const long double &eta ,const long double &alpha){

	//-----Calculate overall net error (RMS-root mean square error - of output neuron errors)
	Layer &outputLayer = layers.back();

	//overwall net error
	error=0.0;

 	for(unsigned n = 0; n < outputLayer.size() -1; n++){
 		long double delta= targetValues[n] - outputLayer[n].getOutputValue();
 		error+=delta*delta;
 	}
 	error*=0.5;

 	//error/=(* numPatterns); //get average error squared
	//error/=outputLayer.size()-1; //get average error squared
    //------ Implement a recent average measurement
    recentAverageError = error;

    //------ Calculate output layer gradients
	for(unsigned n = 0; n < outputLayer.size() -1; n++){
 		outputLayer[n].calculateOutputGradients(targetValues[n]);
  	}

    //------- Calculate hidden layer gradients
  	for(unsigned layerNumber = layers.size() -2; layerNumber >0 ; layerNumber--){
		Layer &hiddenLayer = layers[layerNumber];
		Layer &nextLayer = layers[layerNumber+1];

		for(unsigned n = 0; n < hiddenLayer.size(); n++){
			hiddenLayer[n].calculateHiddenGradients(nextLayer);
  		}
  	}

    //------- For all layers from outputs to first hidden layer,
    //------- update connection weights
  	for(unsigned layerNumber = layers.size() -1; layerNumber >0 ; layerNumber--){
		Layer &layer = layers[layerNumber];
		Layer &prevLayer = layers[layerNumber-1];

		for(unsigned n = 0; n < layer.size() -1; n++){
			layer[n].updateInputWeights(prevLayer,eta,alpha);
		}
  	}

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x80(%rbp)
addq $0x20, %rdi
callq 0x2eb0
movq %rax, %rcx
movq -0x80(%rbp), %rax
movq %rcx, -0x28(%rbp)
fldz
fstpt (%rax)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq %rax, -0x88(%rbp)
movq -0x28(%rbp), %rdi
callq 0x3030
movq %rax, %rcx
movq -0x88(%rbp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x2adb
movq -0x10(%rbp), %rdi
movl -0x2c(%rbp), %eax
movl %eax, %esi
callq 0x3080
fldl (%rax)
fstpt -0x94(%rbp)
movq -0x28(%rbp), %rdi
movl -0x2c(%rbp), %eax
movl %eax, %esi
callq 0x3060
movq %rax, %rdi
callq 0x82d0
movq -0x80(%rbp), %rax
fldt -0x94(%rbp)
fsubp %st, %st(1)
fstpt -0x40(%rbp)
fldt -0x40(%rbp)
fldt (%rax)
fxch %st(1)
fmul %st, %st(0)
faddp %st, %st(1)
fstpt (%rax)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x2a62
movq -0x80(%rbp), %rax
fldt (%rax)
flds 0x8529(%rip)            # 0xb010
fmulp %st, %st(1)
fstpt (%rax)
fldt (%rax)
fstpt 0x10(%rax)
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
movq %rax, -0xa0(%rbp)
movq -0x28(%rbp), %rdi
callq 0x3030
movq %rax, %rcx
movq -0xa0(%rbp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x2b5e
movq -0x28(%rbp), %rdi
movl -0x44(%rbp), %eax
movl %eax, %esi
callq 0x3060
movq %rax, -0xa8(%rbp)
movq -0x10(%rbp), %rdi
movl -0x44(%rbp), %eax
movl %eax, %esi
callq 0x3080
movq -0xa8(%rbp), %rdi
fldl (%rax)
movq %rsp, %rax
fstpt (%rax)
callq 0x8510
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x2af7
movq -0x80(%rbp), %rdi
addq $0x20, %rdi
callq 0x30a0
subq $0x2, %rax
movl %eax, -0x48(%rbp)
cmpl $0x0, -0x48(%rbp)
jbe 0x2c0b
movq -0x80(%rbp), %rdi
addq $0x20, %rdi
movl -0x48(%rbp), %eax
movl %eax, %esi
callq 0x3010
movq -0x80(%rbp), %rdi
movq %rax, -0x50(%rbp)
addq $0x20, %rdi
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, %eax
movl %eax, %esi
callq 0x3010
movq %rax, -0x58(%rbp)
movl $0x0, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
movq %rax, -0xb0(%rbp)
movq -0x50(%rbp), %rdi
callq 0x3030
movq %rax, %rcx
movq -0xb0(%rbp), %rax
cmpq %rcx, %rax
jae 0x2bfb
movq -0x50(%rbp), %rdi
movl -0x5c(%rbp), %eax
movl %eax, %esi
callq 0x3060
movq %rax, %rdi
movq -0x58(%rbp), %rsi
callq 0x8650
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x2bb4
jmp 0x2bfd
movl -0x48(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x2b72
movq -0x80(%rbp), %rdi
addq $0x20, %rdi
callq 0x30a0
subq $0x1, %rax
movl %eax, -0x60(%rbp)
cmpl $0x0, -0x60(%rbp)
jbe 0x2cc4
movq -0x80(%rbp), %rdi
addq $0x20, %rdi
movl -0x60(%rbp), %eax
movl %eax, %esi
callq 0x3010
movq -0x80(%rbp), %rdi
movq %rax, -0x68(%rbp)
addq $0x20, %rdi
movl -0x60(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movl %eax, %esi
callq 0x3010
movq %rax, -0x70(%rbp)
movl $0x0, -0x74(%rbp)
movl -0x74(%rbp), %eax
movq %rax, -0xb8(%rbp)
movq -0x68(%rbp), %rdi
callq 0x3030
movq %rax, %rcx
movq -0xb8(%rbp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x2cb4
movq -0x68(%rbp), %rdi
movl -0x74(%rbp), %eax
movl %eax, %esi
callq 0x3060
movq %rax, %rdi
movq -0x70(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
callq 0x86a0
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0x2c61
jmp 0x2cb6
movl -0x60(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x60(%rbp)
jmp 0x2c1f
addq $0xd0, %rsp
popq %rbp
retq
nopl (%rax)