// File: lns[P]team-tactic-topic-model/main.cpp
// Function: main
int main(int argc, char* argv[])
{
	if(argc<20) {
		printf(" Usage: %s\n",argv[0]);
		printf("    input_file_name\n");
		printf("    out_topics_file_name\n");
		printf("    out_position_file_name\n");
		printf("    out_assign_file_name\n");
		printf("    out_theta_file_name\n");
		printf("    use_pos\n");
		printf("    n_word\n");
		printf("    K\n");
		printf("    alpha\n");
		printf("    beta\n");
		printf("    mu0_x\n");
		printf("    mu0_y\n");
		printf("    kappa0\n");
		printf("    Lambda0_xx\n");
		printf("    Lambda0_xy\n");
		printf("    Lambda0_yy\n");
		printf("    nu0\n");
		printf("    n_iter\n");
		printf("    seed\n");
		printf("  (See main.cpp for details)\n");
		return 0;
	}
	// argv[1] is input, argv[2] is out_topics,
	// argv[3] is out_pos, argv[4] is out_assign,
	// argv[5] is out_theta,
	uint32_t _ = 6; 
	uint32_t use_pos =  strtol(argv[_++],NULL,10);
	uint32_t n_word =   strtol(argv[_++],NULL,10);
	uint32_t K =        strtol(argv[_++],NULL,10);
	double alpha =      strtod(argv[_++],NULL);
	double beta =       strtod(argv[_++],NULL);
	double mu0_x =      strtod(argv[_++],NULL);
	double mu0_y =      strtod(argv[_++],NULL);
	double kappa0 =     strtod(argv[_++],NULL);
	double Lambda0_xx = strtod(argv[_++],NULL);
	double Lambda0_xy = strtod(argv[_++],NULL);
	double Lambda0_yy = strtod(argv[_++],NULL);
	double nu0 =        strtod(argv[_++],NULL);
	uint32_t n_iter =   strtol(argv[_++],NULL,10);
	uint64_t seed =     strtol(argv[_++],NULL,10);

	lcg64(seed);
	LDA<uint32_t,uint32_t,uint8_t> lda;
	// Order matters: 1. Read data. 2. set K. 3. config prior
	//lda.read_lda_c("../hdp/ap/ap.dat");
	lda.read_data(argv[1]);
	lda.n_word = n_word;
	printf("Read file done: %u doc, %u word\n",lda.dat.size(),lda.n_word);
	lda.set_K(K);
	printf("Set K = %u\n",lda.topic.size());
	// alpha, beta, mu0_x, mu0_y, kappa0, Lambda0_xx, Lambda0_xy, Lambda0_yy, nu0
	lda.config({alpha,beta,mu0_x,mu0_y,kappa0,Lambda0_xx,Lambda0_xy,Lambda0_yy,nu0},65536*8);
	lda.use_position = use_pos>0?true:false;

	//lda.print();
	lda.init();
	for(uint32_t i=0;i<n_iter;i++) {
		lda.gibbs();
		if((i+1)%10==0) {
			printf("iter: %u\n",i+1);
			fflush(stdout);
		}
	}
	FILE* f_topic = fopen(argv[2],"w");
	lda.output_topics(f_topic);
	fclose(f_topic);
	FILE* f_pos = fopen(argv[3],"w");
	lda.output_positions(f_pos);
	fclose(f_pos);
	FILE* f_assign = fopen(argv[4],"w");
	lda.output_assignments(f_assign);
	fclose(f_assign);
	FILE* f_theta = fopen(argv[5],"w");
	lda.output_theta(f_theta);
	fclose(f_theta);
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x230, %rsp            # imm = 0x230
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x14, -0x8(%rbp)
jge 0x144c
movq -0x10(%rbp), %rax
movq (%rax), %rsi
leaq 0x8d1f(%rip), %rdi      # 0xa040
movb $0x0, %al
callq 0x1040
leaq 0x8d1d(%rip), %rdi      # 0xa04c
movb $0x0, %al
callq 0x1040
leaq 0x8d24(%rip), %rdi      # 0xa061
movb $0x0, %al
callq 0x1040
leaq 0x8d30(%rip), %rdi      # 0xa07b
movb $0x0, %al
callq 0x1040
leaq 0x8d3e(%rip), %rdi      # 0xa097
movb $0x0, %al
callq 0x1040
leaq 0x8d4a(%rip), %rdi      # 0xa0b1
movb $0x0, %al
callq 0x1040
leaq 0x8d55(%rip), %rdi      # 0xa0ca
movb $0x0, %al
callq 0x1040
leaq 0x8d54(%rip), %rdi      # 0xa0d7
movb $0x0, %al
callq 0x1040
leaq 0x8d52(%rip), %rdi      # 0xa0e3
movb $0x0, %al
callq 0x1040
leaq 0x8d4b(%rip), %rdi      # 0xa0ea
movb $0x0, %al
callq 0x1040
leaq 0x8d48(%rip), %rdi      # 0xa0f5
movb $0x0, %al
callq 0x1040
leaq 0x8d44(%rip), %rdi      # 0xa0ff
movb $0x0, %al
callq 0x1040
leaq 0x8d41(%rip), %rdi      # 0xa10a
movb $0x0, %al
callq 0x1040
leaq 0x8d3e(%rip), %rdi      # 0xa115
movb $0x0, %al
callq 0x1040
leaq 0x8d3c(%rip), %rdi      # 0xa121
movb $0x0, %al
callq 0x1040
leaq 0x8d3e(%rip), %rdi      # 0xa131
movb $0x0, %al
callq 0x1040
leaq 0x8d40(%rip), %rdi      # 0xa141
movb $0x0, %al
callq 0x1040
leaq 0x8d42(%rip), %rdi      # 0xa151
movb $0x0, %al
callq 0x1040
leaq 0x8d3d(%rip), %rdi      # 0xa15a
movb $0x0, %al
callq 0x1040
leaq 0x8d3b(%rip), %rdi      # 0xa166
movb $0x0, %al
callq 0x1040
leaq 0x8d37(%rip), %rdi      # 0xa170
movb $0x0, %al
callq 0x1040
movl $0x0, -0x4(%rbp)
jmp 0x1984
movl $0x6, -0x14(%rbp)
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, %edx
incl %edx
movl %edx, -0x14(%rbp)
movq (%rax,%rcx,8), %rdi
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x210(%rbp)
movl $0xa, %edx
movl %edx, -0x204(%rbp)
callq 0x1160
movq -0x210(%rbp), %rsi
movl -0x204(%rbp), %edx
movl %eax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, %edi
incl %edi
movl %edi, -0x14(%rbp)
movq (%rax,%rcx,8), %rdi
callq 0x1160
movq -0x210(%rbp), %rsi
movl -0x204(%rbp), %edx
movl %eax, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, %edi
incl %edi
movl %edi, -0x14(%rbp)
movq (%rax,%rcx,8), %rdi
callq 0x1160
movq -0x210(%rbp), %rsi
movl %eax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, %edx
incl %edx
movl %edx, -0x14(%rbp)
movq (%rax,%rcx,8), %rdi
callq 0x10c0
movq -0x210(%rbp), %rsi
movsd %xmm0, -0x28(%rbp)
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, %edx
incl %edx
movl %edx, -0x14(%rbp)
movq (%rax,%rcx,8), %rdi
callq 0x10c0
movq -0x210(%rbp), %rsi
movsd %xmm0, -0x30(%rbp)
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, %edx
incl %edx
movl %edx, -0x14(%rbp)
movq (%rax,%rcx,8), %rdi
callq 0x10c0
movq -0x210(%rbp), %rsi
movsd %xmm0, -0x38(%rbp)
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, %edx
incl %edx
movl %edx, -0x14(%rbp)
movq (%rax,%rcx,8), %rdi
callq 0x10c0
movq -0x210(%rbp), %rsi
movsd %xmm0, -0x40(%rbp)
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, %edx
incl %edx
movl %edx, -0x14(%rbp)
movq (%rax,%rcx,8), %rdi
callq 0x10c0
movq -0x210(%rbp), %rsi
movsd %xmm0, -0x48(%rbp)
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, %edx
incl %edx
movl %edx, -0x14(%rbp)
movq (%rax,%rcx,8), %rdi
callq 0x10c0
movq -0x210(%rbp), %rsi
movsd %xmm0, -0x50(%rbp)
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, %edx
incl %edx
movl %edx, -0x14(%rbp)
movq (%rax,%rcx,8), %rdi
callq 0x10c0
movq -0x210(%rbp), %rsi
movsd %xmm0, -0x58(%rbp)
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, %edx
incl %edx
movl %edx, -0x14(%rbp)
movq (%rax,%rcx,8), %rdi
callq 0x10c0
movq -0x210(%rbp), %rsi
movsd %xmm0, -0x60(%rbp)
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, %edx
incl %edx
movl %edx, -0x14(%rbp)
movq (%rax,%rcx,8), %rdi
callq 0x10c0
movq -0x210(%rbp), %rsi
movl -0x204(%rbp), %edx
movsd %xmm0, -0x68(%rbp)
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, %edi
incl %edi
movl %edi, -0x14(%rbp)
movq (%rax,%rcx,8), %rdi
callq 0x1160
movq -0x210(%rbp), %rsi
movl -0x204(%rbp), %edx
movl %eax, -0x6c(%rbp)
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, %edi
incl %edi
movl %edi, -0x14(%rbp)
movq (%rax,%rcx,8), %rdi
callq 0x1160
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdi
callq 0x19a0
leaq -0x178(%rbp), %rdi
movq %rdi, -0x200(%rbp)
callq 0x19c0
movq -0x200(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x1b50
jmp 0x168d
movl -0x1c(%rbp), %eax
movl %eax, -0x174(%rbp)
leaq -0x120(%rbp), %rdi
callq 0x1d00
movq %rax, %rsi
movl -0x174(%rbp), %edx
leaq 0x8adc(%rip), %rdi      # 0xa18e
xorl %eax, %eax
callq 0x1040
jmp 0x16bb
movzbl -0x20(%rbp), %esi
leaq -0x178(%rbp), %rdi
callq 0x1d30
jmp 0x16cd
leaq -0x108(%rbp), %rdi
callq 0x1e60
movq %rax, %rsi
leaq 0x8acc(%rip), %rdi      # 0xa1af
xorl %eax, %eax
callq 0x1040
jmp 0x16ec
movsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x1d0(%rbp)
movsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x1c8(%rbp)
movsd -0x38(%rbp), %xmm0
movsd %xmm0, -0x1c0(%rbp)
movsd -0x40(%rbp), %xmm0
movsd %xmm0, -0x1b8(%rbp)
movsd -0x48(%rbp), %xmm0
movsd %xmm0, -0x1b0(%rbp)
movsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x1a8(%rbp)
movsd -0x58(%rbp), %xmm0
movsd %xmm0, -0x1a0(%rbp)
movsd -0x60(%rbp), %xmm0
movsd %xmm0, -0x198(%rbp)
movsd -0x68(%rbp), %xmm0
movsd %xmm0, -0x190(%rbp)
leaq -0x178(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
movl $0x80000, %edx          # imm = 0x80000
callq 0x1e80
jmp 0x177b
movl -0x18(%rbp), %eax
testl %eax, %eax
setne -0x178(%rbp)
leaq -0x178(%rbp), %rdi
callq 0x1f40
jmp 0x1795
movl $0x0, -0x1d4(%rbp)
movl -0x1d4(%rbp), %eax
cmpl -0x6c(%rbp), %eax
jae 0x1839
leaq -0x178(%rbp), %rdi
xorl %esi, %esi
callq 0x1f60
jmp 0x17be
movl -0x1d4(%rbp), %eax
addl $0x1, %eax
movl $0xa, %ecx
xorl %edx, %edx
divl %ecx
cmpl $0x0, %edx
jne 0x1823
movl -0x1d4(%rbp), %esi
incl %esi
leaq 0x89d7(%rip), %rdi      # 0xa1bb
xorl %eax, %eax
callq 0x1040
jmp 0x17ed
movq 0xd7d4(%rip), %rax      # 0xefc8
movq (%rax), %rdi
callq 0x1130
jmp 0x17fe
jmp 0x1823
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x180(%rbp)
movl %eax, -0x184(%rbp)
leaq -0x178(%rbp), %rdi
callq 0x2650
jmp 0x1990
jmp 0x1825
movl -0x1d4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1d4(%rbp)
jmp 0x179f
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
leaq 0x897d(%rip), %rsi      # 0xa1c5
callq 0x1140
movq %rax, -0x218(%rbp)
jmp 0x1856
movq -0x218(%rbp), %rax
movq %rax, -0x1e0(%rbp)
movq -0x1e0(%rbp), %rsi
leaq -0x178(%rbp), %rdi
callq 0x2130
jmp 0x1879
movq -0x1e0(%rbp), %rdi
callq 0x1100
jmp 0x1887
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
leaq 0x892f(%rip), %rsi      # 0xa1c5
callq 0x1140
movq %rax, -0x220(%rbp)
jmp 0x18a4
movq -0x220(%rbp), %rax
movq %rax, -0x1e8(%rbp)
movq -0x1e8(%rbp), %rsi
leaq -0x178(%rbp), %rdi
callq 0x2220
jmp 0x18c7
movq -0x1e8(%rbp), %rdi
callq 0x1100
jmp 0x18d5
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
leaq 0x88e1(%rip), %rsi      # 0xa1c5
callq 0x1140
movq %rax, -0x228(%rbp)
jmp 0x18f2
movq -0x228(%rbp), %rax
movq %rax, -0x1f0(%rbp)
movq -0x1f0(%rbp), %rsi
leaq -0x178(%rbp), %rdi
callq 0x23f0
jmp 0x1915
movq -0x1f0(%rbp), %rdi
callq 0x1100
jmp 0x1923
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
leaq 0x8893(%rip), %rsi      # 0xa1c5
callq 0x1140
movq %rax, -0x230(%rbp)
jmp 0x1940
movq -0x230(%rbp), %rax
movq %rax, -0x1f8(%rbp)
movq -0x1f8(%rbp), %rsi
leaq -0x178(%rbp), %rdi
callq 0x2530
jmp 0x1963
movq -0x1f8(%rbp), %rdi
callq 0x1100
jmp 0x1971
movl $0x0, -0x4(%rbp)
leaq -0x178(%rbp), %rdi
callq 0x2650
movl -0x4(%rbp), %eax
addq $0x230, %rsp            # imm = 0x230
popq %rbp
retq
movq -0x180(%rbp), %rdi
callq 0x11b0
nopl (%rax)