2014/12/10: バグがあったので修正しました。
グレイマッピングのC++のソースコードです。QAMの信号点にグレイマッピングをする場合に使います。差動・グレー | 情報通信のメモ:を参考に作りました。

サンプルプログラムの使い方

fileソースコードをここからダウンロードします。解凍してコンパイルして引数にQAMの信号点を指定すれば動作します。

gray_mapper.jpg

主要な関数: 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);
}

添付ファイル: filegray_mapper.zip 1653件 [詳細] filegray_mapper.jpg 1631件 [詳細]

  添付編集
Last-modified: 2014-12-10 (水) 12:19:32 (3387d)