Mseq.java

/*
 * $Id: Mseq.java,v 1.14 2008/07/16 15:40:00 koga Exp $
 * 
 * Copyright (C) 2004 Koga Laboratory. All rights reserved.
 */
package org.mklab.tool.matrix;

import org.mklab.nfc.matrix.DoubleMatrix;
import org.mklab.nfc.matrix.IntMatrix;


/**
 * M系列を求めるクラスです。
 * 
 * <p>M sequence
 * 
 * @author koga
 * @version $Revision: 1.14 $
 */
public class Mseq {

  /**
   * メインメソッド
   * 
   * @param args コマンドライン引数
   */
  public static void main(String[] args) {
    DoubleMatrix s = mseq(10);
    s.print("s"); //$NON-NLS-1$
  }

  /**
   * M系列を返します。
   * 
   * @param n レジスタ数
   * @return M系列 (M sequence)
   */
  public static DoubleMatrix mseq(int n) {
    int smp = 1;
    return mseq(n, smp);
  }

  /**
   * M系列を返します。
   * 
   * @param n レジスタの数 (number of register)
   * @param smp 同じ値が続く数 (number of consecutive points with the same value)
   * @return M系列 (M sequence)
   */
  public static DoubleMatrix mseq(int n, int smp) {
    double[] xx;
    // Initialization of registers
    switch (n) {
      case 2:
        xx = new double[] {1, 1};
        break;
      case 3:
        xx = new double[] {1, -1, 1};
        break;
      case 4:
        xx = new double[] {1, -1, -1, 1};
        break;
      case 5:
        xx = new double[] {-1, 1, -1, -1, 1};
        break;
      case 6:
        xx = new double[] {1, -1, -1, -1, -1, 1};
        break;
      case 7:
        xx = new double[] {1, -1, -1, -1, -1, -1, 1};
        break;
      case 9:
        xx = new double[] {-1, -1, -1, 1, -1, -1, -1, -1, 1};
        break;
      case 10:
        xx = new double[] {-1, -1, 1, -1, -1, -1, -1, -1, -1, 1};
        break;
      case 11:
        xx = new double[] {-1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1};
        break;
      case 15:
        xx = new double[] {1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1};
        break;
      default:
        throw new IllegalArgumentException(Messages.getString("Mseq.0")); //$NON-NLS-1$
    }

    DoubleMatrix x = new DoubleMatrix(xx);

    int N = (int)(Math.pow(2, n) - 1);
    DoubleMatrix M = new DoubleMatrix(1, N * smp);
    DoubleMatrix one = DoubleMatrix.ones(1, smp);

    for (int k = 1; k <= N; k++) {
      M.setSubMatrix(1, 1, (k - 1) * smp + 1, k * smp, one.multiply(x.getDoubleElement(n)));
      updateRegister(x);
    }

    return M;
  }

  /**
   * レジスターを更新します。
   * 
   * @param x レジスターの値
   */
  private static void updateRegister(DoubleMatrix x) {
    int n = x.getColumnSize();
    double x1;

    switch (n) {
      case 2:
        if (x.getDoubleElement(1) == x.getDoubleElement(2)) {
          x1 = -1.0;
        } else {
          x1 = 1.0;
        }
        break;
      case 3:
        if (x.getDoubleElement(1) == x.getDoubleElement(3)) {
          x1 = -1.0;
        } else {
          x1 = 1.0;
        }
        break;
      case 4:
        if (x.getDoubleElement(1) == x.getDoubleElement(4)) {
          x1 = -1.0;
        } else {
          x1 = 1.0;
        }
        break;
      case 5:
        if (x.getDoubleElement(2) == x.getDoubleElement(5)) {
          x1 = -1.0;
        } else {
          x1 = 1.0;
        }
        break;
      case 6:
        if (x.getDoubleElement(1) == x.getDoubleElement(6)) {
          x1 = -1.0;
        } else {
          x1 = 1.0;
        }
        break;
      case 7:
        if (x.getDoubleElement(1) == x.getDoubleElement(7)) {
          x1 = -1.0;
        } else {
          x1 = 1.0;
        }
        break;
      case 9:
        if (x.getDoubleElement(4) == x.getDoubleElement(9)) {
          x1 = -1.0;
        } else {
          x1 = 1.0;
        }
        break;
      case 10:
        if (x.getDoubleElement(3) == x.getDoubleElement(10)) {
          x1 = -1.0;
        } else {
          x1 = 1.0;
        }
        break;
      case 11:
        if (x.getDoubleElement(2) == x.getDoubleElement(11)) {
          x1 = -1.0;
        } else {
          x1 = 1.0;
        }
        break;
      case 15:
        if (x.getDoubleElement(1) == x.getDoubleElement(15)) {
          x1 = -1.0;
        } else {
          x1 = 1.0;
        }
        break;
      default:
        throw new IllegalArgumentException(Messages.getString("Mseq.1")); //$NON-NLS-1$
    }

    x.setSubVector(IntMatrix.series(2, n), x.getSubVector(1, n - 1));
    x.setElement(1, x1);
  }

}