2014/12/10: バグがあったので修正しました。 サンプルプログラムの使い方 †ソースコードをここからダウンロードします。解凍してコンパイルして引数にQAMの信号点を指定すれば動作します。 主要な関数: make_gray_label †グレイラベルを作成する関数。引数のsizeには信号点の数を入れます。uimatはuint16_t(16bitのunsigned int)の行列用の自作関数です。2次元配列を**qamとかで渡してqam[1][1]とかでアクセスしたかったので作りました。2次元配列は少しポインタが面倒くさい... void make_gray_label(int size, uint16_t **qam) { uint16_t **qpsk_base = uimat_alloc(2, 2); qpsk_base[0][0] = 1; qpsk_base[0][1] = 0; qpsk_base[1][0] = 3; qpsk_base[1][1] = 2; if(size == 4){ qam[0][0] = 1; qam[0][1] = 0; qam[1][0] = 3; qam[1][1] = 2; return; } if(size == 0){ printf("illigal input\n"); exit(-1); } int n = (int) round(sqrt(size)); int m = n; int num_bits = uint16_log2(n) * 2; int pre_n = n / 2; int pre_m = m / 2; uint16_t **table00 = uimat_alloc(pre_n, pre_m); uint16_t **table01 = uimat_alloc(pre_n, pre_m); uint16_t **table10 = uimat_alloc(pre_n, pre_m); uint16_t **table11 = uimat_alloc(pre_n, pre_m); make_gray_label(pre_n * pre_m, table11); uimat_copy(table01, table11, pre_n, pre_m); uimat_left2right(table01, pre_n, pre_m); uimat_copy(table00, table01, pre_n, pre_m); uimat_up2down(table00, pre_n, pre_m); uimat_copy(table10, table00, pre_n, pre_m); uimat_left2right(table10, pre_n, pre_m); uint16_t **lower = uimat_alloc(n, m); uimat_conjunct(lower, table01, table11, table00, table10, n, m); uint16_t **upper =uimat_alloc(n, m); uimat_expand4(upper, qpsk_base, n, m); uimat_shift(num_bits - 2, upper, n, m); uimat_add(qam, upper, lower, n, m); uimat_free(table00, pre_n, pre_m); uimat_free(table01, pre_n, pre_m); uimat_free(table10, pre_n, pre_m); uimat_free(table11, pre_n, pre_m); uimat_free(upper, n, m); uimat_free(lower, n, m); uimat_free(qpsk_base, 2, 2); } |