// File: xbai0624[P]dnn/src/ConstructLayer.cpp
// Function: ConstructLayer::GetSigmaSquareFor1DLayer(std::vector<Images, std::allocator<Images>>&, Images&, Images&)
void ConstructLayer::GetSigmaSquareFor1DLayer(std::vector<Images> &source, Images &mu, Images &sigma_square)
{
    // get \sigma_B^2
    // --- 1D layer

    double batch_size = source.size();
    assert(batch_size > 0);
    size_t nKernel = source[0].OutputImageFromKernel.size();
    assert(nKernel == 1);
    assert(mu.OutputImageFromKernel.size() == 1);

    auto dim = source[0].OutputImageFromKernel[0].Dimension();
    Matrix tmp_sigma_square(dim, 0);

    Matrix & average = mu.OutputImageFromKernel[0];

    for(int i=0;i<(int)batch_size;i++)
    {
        Matrix & tmp_kernel_image = source[i].OutputImageFromKernel[0];

        Matrix _t1 = tmp_kernel_image - average;
        Matrix _t1_square = _t1^_t1;

        tmp_sigma_square = tmp_sigma_square + _t1_square;
    }

    tmp_sigma_square = tmp_sigma_square / batch_size;
    tmp_sigma_square = tmp_sigma_square * batch_size / (batch_size - 1.); // Var[x]^2 = E(\sigma)^2 * m / (m-1)

    sigma_square.OutputImageFromKernel.clear();
    sigma_square.OutputImageFromKernel.push_back(tmp_sigma_square);
}

// Assembly:
subq $0x128, %rsp            # imm = 0x128
movq %rdi, 0x120(%rsp)
movq %rsi, 0x118(%rsp)
movq %rdx, 0x110(%rsp)
movq %rcx, 0x108(%rsp)
movq 0x118(%rsp), %rdi
callq 0x1ff40
movq %rax, %xmm0
movaps 0x40cd0(%rip), %xmm1    # 0x52060
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0x40cd4(%rip), %xmm1    # 0x52070
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movsd %xmm0, 0x100(%rsp)
movsd 0x100(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x113c8
jmp 0x113e7
leaq 0x41644(%rip), %rdi     # 0x52a13
leaq 0x40dfc(%rip), %rsi     # 0x521d2
movl $0x7ab, %edx            # imm = 0x7AB
leaq 0x41640(%rip), %rcx     # 0x52a22
callq 0x4170
movq 0x118(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1fd40
movq %rax, %rdi
callq 0x1f9c0
movq %rax, 0xf8(%rsp)
cmpq $0x1, 0xf8(%rsp)
jne 0x11415
jmp 0x11434
leaq 0x41667(%rip), %rdi     # 0x52a83
leaq 0x40daf(%rip), %rsi     # 0x521d2
movl $0x7ad, %edx            # imm = 0x7AD
leaq 0x415f3(%rip), %rcx     # 0x52a22
callq 0x4170
movq 0x110(%rsp), %rdi
callq 0x1f9c0
cmpq $0x1, %rax
jne 0x11449
jmp 0x11468
leaq 0x41640(%rip), %rdi     # 0x52a90
leaq 0x40d7b(%rip), %rsi     # 0x521d2
movl $0x7ae, %edx            # imm = 0x7AE
leaq 0x415bf(%rip), %rcx     # 0x52a22
callq 0x4170
movq 0x118(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1fd40
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1f9e0
movq %rax, %rdi
callq 0x3bae0
movq %rax, 0xe8(%rsp)
movq %rdx, 0xf0(%rsp)
movq 0xe8(%rsp), %rax
movq %rax, 0xc0(%rsp)
movq 0xf0(%rsp), %rax
movq %rax, 0xc8(%rsp)
movq 0xc0(%rsp), %rsi
movq 0xc8(%rsp), %rdx
leaq 0xd0(%rsp), %rdi
xorps %xmm0, %xmm0
callq 0x3b680
movq 0x110(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1f9e0
movq %rax, 0xb8(%rsp)
movl $0x0, 0xb4(%rsp)
movl 0xb4(%rsp), %eax
cvttsd2si 0x100(%rsp), %ecx
cmpl %ecx, %eax
jge 0x1165b
movq 0x118(%rsp), %rdi
movslq 0xb4(%rsp), %rsi
callq 0x1fd40
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1f9e0
movq %rax, 0xa8(%rsp)
movq 0xa8(%rsp), %rsi
movq 0xb8(%rsp), %rdx
leaq 0x90(%rsp), %rdi
callq 0x3c480
jmp 0x11561
leaq 0x68(%rsp), %rdi
leaq 0x90(%rsp), %rdx
movq %rdx, %rsi
callq 0x3c680
jmp 0x11578
leaq 0x50(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
leaq 0x68(%rsp), %rdx
callq 0x3bf90
jmp 0x11591
leaq 0xd0(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x1fa20
jmp 0x115a5
leaq 0x50(%rsp), %rdi
callq 0x3bb80
leaq 0x68(%rsp), %rdi
callq 0x3bb80
leaq 0x90(%rsp), %rdi
callq 0x3bb80
movl 0xb4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb4(%rsp)
jmp 0x11501
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x88(%rsp)
movl %eax, 0x84(%rsp)
jmp 0x11798
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x88(%rsp)
movl %eax, 0x84(%rsp)
jmp 0x11649
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x88(%rsp)
movl %eax, 0x84(%rsp)
jmp 0x1163f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x88(%rsp)
movl %eax, 0x84(%rsp)
leaq 0x50(%rsp), %rdi
callq 0x3bb80
leaq 0x68(%rsp), %rdi
callq 0x3bb80
leaq 0x90(%rsp), %rdi
callq 0x3bb80
jmp 0x11798
movsd 0x100(%rsp), %xmm0
leaq 0x38(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0x3d140
jmp 0x11678
leaq 0xd0(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x1fa20
jmp 0x1168c
leaq 0x38(%rsp), %rdi
callq 0x3bb80
movsd 0x100(%rsp), %xmm0
leaq 0x8(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0x3cfd0
jmp 0x116b3
movsd 0x100(%rsp), %xmm0
movsd 0x40964(%rip), %xmm1    # 0x52028
addsd %xmm1, %xmm0
leaq 0x20(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x3d140
jmp 0x116d9
leaq 0xd0(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x1fa20
jmp 0x116ed
leaq 0x20(%rsp), %rdi
callq 0x3bb80
leaq 0x8(%rsp), %rdi
callq 0x3bb80
movq 0x108(%rsp), %rdi
callq 0x1fa00
movq 0x108(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0x1fa50
jmp 0x11725
leaq 0xd0(%rsp), %rdi
callq 0x3bb80
addq $0x128, %rsp            # imm = 0x128
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x88(%rsp)
movl %eax, 0x84(%rsp)
leaq 0x38(%rsp), %rdi
callq 0x3bb80
jmp 0x11798
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x88(%rsp)
movl %eax, 0x84(%rsp)
jmp 0x1178e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x88(%rsp)
movl %eax, 0x84(%rsp)
leaq 0x20(%rsp), %rdi
callq 0x3bb80
leaq 0x8(%rsp), %rdi
callq 0x3bb80
leaq 0xd0(%rsp), %rdi
callq 0x3bb80
movq 0x88(%rsp), %rdi
callq 0x43f0
nopw %cs:(%rax,%rax)