// File: istellartech[P]OpenTsiolkovsky/src/fileio.cpp
// Function: interp_matrix_2d(double, double, Eigen::Matrix<double, -1, -1, 0, -1, -1>)
double interp_matrix_2d(double mach, double alpha, MatrixXd matrix){
    // 2変数関数として線形補間をする。範囲外のデータが入力された場合強制終了。
    // 先頭行先頭列に変数を並べる
    // @params mach  取得したいデータ縦方向
    // @params alpha 取得したいデータ横方向
    // @params matrix 2x? データ配列
    // @return y(double) 入力mach, alphaのデータ
    const int col_number = 15;
    double y;

    int index_mach, index_alpha;
    double Dmach = -1;
    double Dalpha = -1;

    // search index mach and calculate Dmach
    if(mach < matrix(1, 0) || mach > matrix(matrix.rows()-1, 0)){
        std::cout << "ERROR : interp_matrix_2d. First argument is out of the boundary of matrix.";
        exit(1);
    }
    for (int i = 2; i < matrix.rows(); i++) {
        if(mach < matrix(i, 0)){
            index_mach = i - 1;

            double mach_lower, mach_higher;
            mach_lower  = matrix(i - 1, 0);
            mach_higher = matrix(    i, 0);
            Dmach = (mach - mach_lower)/(mach_higher - mach_lower);

            break;
        }
    }
    

    // search index alpha and calculate Dalpha
    if(alpha < matrix(0, 1) || alpha > matrix(0, col_number -1)){
        std::cout << "ERROR : interp_matrix_2d. Second argument is out of the boundary of matrix.";
        exit(1);
    }
    for (int i = 2; i < col_number; i++) {
        if(alpha < matrix(0, i)){
            index_alpha = i - 1;

            double alpha_lower, alpha_higher;
            alpha_lower  = matrix(0, i - 1);
            alpha_higher = matrix(0,     i);
            Dalpha = (alpha - alpha_lower)/(alpha_higher - alpha_lower);

            break;
        }
    }

    // calculate y
    if(Dmach < 0.5){
        if(Dalpha < 0.5){
            y = matrix(index_mach, index_alpha)
              + ( matrix(index_mach + 1, index_alpha) - matrix(index_mach, index_alpha)) * Dmach
              + ( matrix(index_mach, index_alpha + 1) - matrix(index_mach, index_alpha)) * Dalpha;
        }else{
            y = matrix(index_mach, index_alpha + 1)
              + ( matrix(index_mach + 1, index_alpha + 1) - matrix(index_mach, index_alpha + 1)) * Dmach
              + ( matrix(index_mach, index_alpha + 1) - matrix(index_mach, index_alpha)) * (Dalpha - 1);
        }
    }else{
        if(Dalpha < 0.5){
            y = matrix(index_mach + 1, index_alpha)
              + ( matrix(index_mach + 1, index_alpha) - matrix(index_mach, index_alpha)) * (Dmach - 1)
              + ( matrix(index_mach + 1, index_alpha + 1) - matrix(index_mach + 1, index_alpha)) * Dalpha;
        }else{
            y = matrix(index_mach + 1, index_alpha + 1)
              + ( matrix(index_mach + 1, index_alpha + 1) - matrix(index_mach, index_alpha + 1)) * (Dmach - 1)
              + ( matrix(index_mach + 1, index_alpha + 1) - matrix(index_mach + 1, index_alpha)) * (Dalpha - 1);
        }
    }

    return y;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x130, %rsp            # imm = 0x130
movq %rdi, -0x80(%rbp)
movsd %xmm0, -0x8(%rbp)
movsd %xmm1, -0x10(%rbp)
movq %rdi, -0x18(%rbp)
movl $0xf, -0x1c(%rbp)
movsd 0x1775c(%rip), %xmm0    # 0x52e68
movsd %xmm0, -0x38(%rbp)
movsd 0x1774f(%rip), %xmm0    # 0x52e68
movsd %xmm0, -0x40(%rbp)
movsd -0x8(%rbp), %xmm0
movsd %xmm0, -0x78(%rbp)
movl $0x1, %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x8540
movsd -0x78(%rbp), %xmm1
movsd (%rax), %xmm0
ucomisd %xmm1, %xmm0
ja 0x3b77d
movq -0x80(%rbp), %rdi
movsd -0x8(%rbp), %xmm0
movsd %xmm0, -0x88(%rbp)
callq 0x8490
movq -0x80(%rbp), %rdi
movq %rax, %rsi
subq $0x1, %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x8540
movsd -0x88(%rbp), %xmm0
ucomisd (%rax), %xmm0
jbe 0x3b79a
movq 0x3d82c(%rip), %rdi     # 0x78fb0
leaq 0x1d74e(%rip), %rsi     # 0x58ed9
callq 0x6460
movl $0x1, %edi
callq 0x6580
movl $0x2, -0x44(%rbp)
movq -0x80(%rbp), %rdi
movslq -0x44(%rbp), %rax
movq %rax, -0x90(%rbp)
callq 0x8490
movq %rax, %rcx
movq -0x90(%rbp), %rax
cmpq %rcx, %rax
jge 0x3b869
movq -0x80(%rbp), %rdi
movsd -0x8(%rbp), %xmm0
movsd %xmm0, -0x98(%rbp)
movslq -0x44(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x8540
movsd -0x98(%rbp), %xmm1
movsd (%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x3b859
movq -0x80(%rbp), %rdi
movl -0x44(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x2c(%rbp)
movl -0x44(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x8540
movq -0x80(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x50(%rbp)
movslq -0x44(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x8540
movsd (%rax), %xmm0
movsd %xmm0, -0x58(%rbp)
movsd -0x8(%rbp), %xmm0
subsd -0x50(%rbp), %xmm0
movsd -0x58(%rbp), %xmm1
subsd -0x50(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x38(%rbp)
jmp 0x3b869
jmp 0x3b85b
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x3b7a1
movq -0x80(%rbp), %rdi
movsd -0x10(%rbp), %xmm0
movsd %xmm0, -0xa0(%rbp)
xorl %eax, %eax
movl %eax, %esi
movl $0x1, %edx
callq 0x8540
movsd -0xa0(%rbp), %xmm1
movsd (%rax), %xmm0
ucomisd %xmm1, %xmm0
ja 0x3b8c7
movq -0x80(%rbp), %rdi
movsd -0x10(%rbp), %xmm0
movsd %xmm0, -0xa8(%rbp)
xorl %eax, %eax
movl %eax, %esi
movl $0xe, %edx
callq 0x8540
movsd -0xa8(%rbp), %xmm0
ucomisd (%rax), %xmm0
jbe 0x3b8e4
movq 0x3d6e2(%rip), %rdi     # 0x78fb0
leaq 0x1d64f(%rip), %rsi     # 0x58f24
callq 0x6460
movl $0x1, %edi
callq 0x6580
movl $0x2, -0x5c(%rbp)
cmpl $0xf, -0x5c(%rbp)
jge 0x3b996
movq -0x80(%rbp), %rdi
movsd -0x10(%rbp), %xmm0
movsd %xmm0, -0xb0(%rbp)
movslq -0x5c(%rbp), %rdx
xorl %eax, %eax
movl %eax, %esi
callq 0x8540
movsd -0xb0(%rbp), %xmm1
movsd (%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x3b986
movq -0x80(%rbp), %rdi
movl -0x5c(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x30(%rbp)
movl -0x5c(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rdx
xorl %eax, %eax
movl %eax, %esi
callq 0x8540
movq -0x80(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x68(%rbp)
movslq -0x5c(%rbp), %rdx
xorl %eax, %eax
movl %eax, %esi
callq 0x8540
movsd (%rax), %xmm0
movsd %xmm0, -0x70(%rbp)
movsd -0x10(%rbp), %xmm0
subsd -0x68(%rbp), %xmm0
movsd -0x70(%rbp), %xmm1
subsd -0x68(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rbp)
jmp 0x3b996
jmp 0x3b988
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x3b8eb
movsd 0x174c2(%rip), %xmm0    # 0x52e60
ucomisd -0x38(%rbp), %xmm0
jbe 0x3bb85
movsd 0x174af(%rip), %xmm0    # 0x52e60
ucomisd -0x40(%rbp), %xmm0
jbe 0x3ba93
movq -0x80(%rbp), %rdi
movslq -0x2c(%rbp), %rsi
movslq -0x30(%rbp), %rdx
callq 0x8540
movq -0x80(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0xc8(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
movslq -0x30(%rbp), %rdx
callq 0x8540
movq -0x80(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0xd0(%rbp)
movslq -0x2c(%rbp), %rsi
movslq -0x30(%rbp), %rdx
callq 0x8540
movsd -0xd0(%rbp), %xmm0
movsd -0xc8(%rbp), %xmm1
movq -0x80(%rbp), %rdi
subsd (%rax), %xmm0
movsd -0x38(%rbp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xb8(%rbp)
movslq -0x2c(%rbp), %rsi
movl -0x30(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdx
callq 0x8540
movq -0x80(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0xc0(%rbp)
movslq -0x2c(%rbp), %rsi
movslq -0x30(%rbp), %rdx
callq 0x8540
movsd -0xc0(%rbp), %xmm0
movsd -0xb8(%rbp), %xmm1
subsd (%rax), %xmm0
movsd -0x40(%rbp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x28(%rbp)
jmp 0x3bb80
movq -0x80(%rbp), %rdi
movslq -0x2c(%rbp), %rsi
movl -0x30(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdx
callq 0x8540
movq -0x80(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0xe8(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
movl -0x30(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdx
callq 0x8540
movq -0x80(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0xf0(%rbp)
movslq -0x2c(%rbp), %rsi
movl -0x30(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdx
callq 0x8540
movsd -0xf0(%rbp), %xmm0
movsd -0xe8(%rbp), %xmm1
movq -0x80(%rbp), %rdi
subsd (%rax), %xmm0
movsd -0x38(%rbp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xd8(%rbp)
movslq -0x2c(%rbp), %rsi
movl -0x30(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdx
callq 0x8540
movq -0x80(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0xe0(%rbp)
movslq -0x2c(%rbp), %rsi
movslq -0x30(%rbp), %rdx
callq 0x8540
movsd -0xe0(%rbp), %xmm0
movsd -0xd8(%rbp), %xmm1
subsd (%rax), %xmm0
movsd -0x40(%rbp), %xmm2
movsd 0x164d1(%rip), %xmm3    # 0x52040
subsd %xmm3, %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x28(%rbp)
jmp 0x3bd94
movsd 0x172d3(%rip), %xmm0    # 0x52e60
ucomisd -0x40(%rbp), %xmm0
jbe 0x3bc8a
movq -0x80(%rbp), %rdi
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
movslq -0x30(%rbp), %rdx
callq 0x8540
movq -0x80(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x108(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
movslq -0x30(%rbp), %rdx
callq 0x8540
movq -0x80(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x110(%rbp)
movslq -0x2c(%rbp), %rsi
movslq -0x30(%rbp), %rdx
callq 0x8540
movsd -0x110(%rbp), %xmm0
movsd -0x108(%rbp), %xmm1
movq -0x80(%rbp), %rdi
subsd (%rax), %xmm0
movsd -0x38(%rbp), %xmm2
movsd 0x1642e(%rip), %xmm3    # 0x52040
subsd %xmm3, %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xf8(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
movl -0x30(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdx
callq 0x8540
movq -0x80(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x100(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
movslq -0x30(%rbp), %rdx
callq 0x8540
movsd -0x100(%rbp), %xmm0
movsd -0xf8(%rbp), %xmm1
subsd (%rax), %xmm0
movsd -0x40(%rbp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x28(%rbp)
jmp 0x3bd92
movq -0x80(%rbp), %rdi
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
movl -0x30(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdx
callq 0x8540
movq -0x80(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x128(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
movl -0x30(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdx
callq 0x8540
movq -0x80(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x130(%rbp)
movslq -0x2c(%rbp), %rsi
movl -0x30(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdx
callq 0x8540
movsd -0x130(%rbp), %xmm0
movsd -0x128(%rbp), %xmm1
movq -0x80(%rbp), %rdi
subsd (%rax), %xmm0
movsd -0x38(%rbp), %xmm2
movsd 0x1632d(%rip), %xmm3    # 0x52040
subsd %xmm3, %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x118(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
movl -0x30(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdx
callq 0x8540
movq -0x80(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x120(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
movslq -0x30(%rbp), %rdx
callq 0x8540
movsd -0x120(%rbp), %xmm0
movsd -0x118(%rbp), %xmm1
subsd (%rax), %xmm0
movsd -0x40(%rbp), %xmm2
movsd 0x162bf(%rip), %xmm3    # 0x52040
subsd %xmm3, %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x28(%rbp)
jmp 0x3bd94
movsd -0x28(%rbp), %xmm0
addq $0x130, %rsp            # imm = 0x130
popq %rbp
retq
nopw %cs:(%rax,%rax)