// File: iu-vail[P]iprimal/iPrimal.cpp
// Function: Primal::SwapTasks()
void
Primal::SwapTasks(void){

  double augment_delta = 0;
  cell c_first = swap_loop.back();
  if(!swap_loop.empty()){
    // the first cell in the loop is special
    // only the column corresponding the first cell need to be adjusted

    // get the first cell, which was stored reversely
    augment_delta = - (oprt_matrix[c_first.row_idx][c_first.col_idx] + deltas[c_first.col_idx] - deltas[GetAssignedCol(c_first.row_idx)] );
    assert(augment_delta>=0);
    _cout("Augment delta: "<<augment_delta<<endl);
  }

  _cout("Before swaps:"<<endl);
  DisplayMatrix(oprt_matrix);

  // update dual variables
  for(uint i=0; i<col_size; i++){
    dual_col_vars[i] -= deltas[i];
    dual_row_vars[i] += deltas[GetAssignedCol(i)];
  }
  if(!swap_loop.empty()){
    // also specially process the starting col, to augment the sum
    dual_col_vars[c_first.col_idx] -= augment_delta;
  }

  _cout("Update dual cols: ");
  DisplayVec<double>(dual_col_vars);
  _cout("Update dual rows: ");
  DisplayVec<double>(dual_row_vars);

  UpdateReducedCostMatrix(dual_row_vars, dual_col_vars);

  // swap the tasks in the assignment vector
  // only need the odd-numbered cell from the loop
  for(list<cell>::reverse_iterator itr=swap_loop.rbegin(); itr!=swap_loop.rend(); itr++){
    cell c_odd = *itr++;
    assert(oprt_matrix[c_odd.row_idx][c_odd.col_idx] < DOUBLE_EPSILON);
    assignment[c_odd.row_idx] = c_odd.col_idx;
  } 

  _cout("After swaps:"<<endl);
  DisplayMatrix(oprt_matrix);
  _cout(endl);

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x50(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x10(%rbp)
addq $0x110, %rdi            # imm = 0x110
callq 0xb480
movq -0x50(%rbp), %rdi
movq (%rax), %rax
movq %rax, -0x18(%rbp)
addq $0x110, %rdi            # imm = 0x110
callq 0xb4c0
testb $0x1, %al
jne 0x963c
movq -0x50(%rbp), %rdi
addq $0xc8, %rdi
movslq -0x18(%rbp), %rsi
callq 0x4330
movq %rax, %rdi
movslq -0x14(%rbp), %rsi
callq 0x43e0
movq -0x50(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x68(%rbp)
addq $0x38, %rdi
movslq -0x14(%rbp), %rsi
callq 0x43e0
movsd -0x68(%rbp), %xmm0
movq -0x50(%rbp), %rdi
addsd (%rax), %xmm0
movsd %xmm0, -0x58(%rbp)
movq %rdi, %rax
addq $0x38, %rax
movq %rax, -0x60(%rbp)
movl -0x18(%rbp), %esi
callq 0xb100
movq -0x60(%rbp), %rdi
movl %eax, %eax
movl %eax, %esi
callq 0x43e0
movsd -0x58(%rbp), %xmm0
subsd (%rax), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, -0x10(%rbp)
movsd -0x10(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x961b
jmp 0x963a
leaq 0x10c5c(%rip), %rdi     # 0x1a27e
leaq 0x10a9e(%rip), %rsi     # 0x1a0c7
movl $0x29f, %edx            # imm = 0x29F
leaq 0x10c5a(%rip), %rcx     # 0x1a28f
callq 0x3190
jmp 0x963c
movq -0x50(%rbp), %rdi
movq %rdi, %rsi
addq $0xc8, %rsi
callq 0x6c00
movl $0x0, -0x1c(%rbp)
movq -0x50(%rbp), %rcx
movl -0x1c(%rbp), %eax
cmpl 0x4(%rcx), %eax
jae 0x96fe
movq -0x50(%rbp), %rdi
addq $0x38, %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x43e0
movq -0x50(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x80(%rbp)
addq $0x20, %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x43e0
movsd -0x80(%rbp), %xmm1
movq -0x50(%rbp), %rdi
movsd (%rax), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movq %rdi, %rax
addq $0x38, %rax
movq %rax, -0x78(%rbp)
movl -0x1c(%rbp), %esi
callq 0xb100
movq -0x78(%rbp), %rdi
movl %eax, %eax
movl %eax, %esi
callq 0x43e0
movq -0x50(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x70(%rbp)
addq $0x8, %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x43e0
movsd -0x70(%rbp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x9656
movq -0x50(%rbp), %rdi
addq $0x110, %rdi            # imm = 0x110
callq 0xb4c0
testb $0x1, %al
jne 0x9744
movq -0x50(%rbp), %rdi
movsd -0x10(%rbp), %xmm0
movsd %xmm0, -0x88(%rbp)
addq $0x20, %rdi
movslq -0x14(%rbp), %rsi
callq 0x43e0
movsd -0x88(%rbp), %xmm1
movsd (%rax), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movq -0x50(%rbp), %rdi
movq %rdi, %rsi
addq $0x20, %rsi
callq 0xb330
movq -0x50(%rbp), %rdi
movq %rdi, %rsi
addq $0x8, %rsi
callq 0xb330
movq -0x50(%rbp), %rdi
movq %rdi, %rsi
addq $0x8, %rsi
movq %rdi, %rdx
addq $0x20, %rdx
callq 0x7b10
movq -0x50(%rbp), %rsi
addq $0x110, %rsi            # imm = 0x110
leaq -0x28(%rbp), %rdi
callq 0xb4e0
movq -0x50(%rbp), %rsi
addq $0x110, %rsi            # imm = 0x110
leaq -0x30(%rbp), %rdi
callq 0xb560
leaq -0x28(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0xb530
testb $0x1, %al
jne 0x97b9
jmp 0x9860
leaq -0x40(%rbp), %rdi
leaq -0x28(%rbp), %rsi
xorl %edx, %edx
callq 0xb5b0
leaq -0x40(%rbp), %rdi
callq 0xb5f0
movq -0x50(%rbp), %rdi
movq (%rax), %rax
movq %rax, -0x38(%rbp)
addq $0xc8, %rdi
movslq -0x38(%rbp), %rsi
callq 0x4330
movq %rax, %rdi
movslq -0x34(%rbp), %rsi
callq 0x43e0
movsd 0x10890(%rip), %xmm0    # 0x1a090
ucomisd (%rax), %xmm0
jbe 0x9808
jmp 0x9827
leaq 0x10a99(%rip), %rdi     # 0x1a2a8
leaq 0x108b1(%rip), %rsi     # 0x1a0c7
movl $0x2bb, %edx            # imm = 0x2BB
leaq 0x10a6d(%rip), %rcx     # 0x1a28f
callq 0x3190
movq -0x50(%rbp), %rdi
movl -0x34(%rbp), %eax
movl %eax, -0x8c(%rbp)
addq $0xf8, %rdi
movslq -0x38(%rbp), %rsi
callq 0xa4e0
movl -0x8c(%rbp), %ecx
movl %ecx, (%rax)
leaq -0x48(%rbp), %rdi
leaq -0x28(%rbp), %rsi
xorl %edx, %edx
callq 0xb5b0
jmp 0x978f
movq -0x50(%rbp), %rdi
movq %rdi, %rsi
addq $0xc8, %rsi
callq 0x6c00
addq $0x90, %rsp
popq %rbp
retq
nopl (%rax)