Idft.java

/*
 * $Id: Idft.java,v 1.20 2008/03/15 00:23:40 koga Exp $
 * 
 * Copyright (C) 2004 Koga Laboratory. All rights reserved.
 */
package org.mklab.tool.matrix;

import java.io.IOException;

import org.mklab.nfc.matrix.DoubleComplexMatrix;
import org.mklab.nfc.matrix.DoubleMatrix;
import org.mklab.nfc.matrix.IntMatrix;
import org.mklab.nfc.scalar.DoubleComplexNumber;
import org.mklab.nfc.scalar.DoubleNumber;
import org.mklab.tool.graph.gnuplot.Canvas;
import org.mklab.tool.graph.gnuplot.Gnuplot;


/**
 * 逆離散フーリエ変換の結果を求めるクラスです。
 * 
 * <p>Inverse discrete Fourier transform
 * 
 * @author koga
 * @version $Revision: 1.20 $
 * @see org.mklab.tool.matrix.Dft
 */
public class Idft {

  /**
   * @param Y_ データ
   * @return 逆離散フーリエ変換の結果 (transformed result)
   */
  public static DoubleComplexMatrix idft(DoubleMatrix Y_) {
    int N = Y_.getColumnSize();
    return idft(Y_, N);
  }

  /**
   * ベクトル <code>X</code> の逆離散フーリエ変換を計算します。
   * 
   * @param Y_ データ
   * @param size データ数
   * @return 逆離散フーリエ変換の結果 (transformed result)
   */
  public static DoubleComplexMatrix idft(DoubleMatrix Y_, int size) {
    DoubleMatrix Y = Y_;

    DoubleNumber unit = Y.getElement(1, 1);
    DoubleComplexNumber j = new DoubleComplexNumber(0,1);
    DoubleNumber pi = unit.createPI();

    int n = Y.getColumnSize();
    if (size < n) {
      Y = Y.getSubMatrix(1, Y.getRowSize(), 1, size);
    } else if (size > n) {
      Y = Y.appendRight(unit.createZeroGrid(Y.getRowSize(), size - n));
    }

    int Nr = size;
    DoubleMatrix W0 = new DoubleMatrix(IntMatrix.series(0, Nr - 1)).divide(Nr).transpose().multiply(pi.multiply(2));
    DoubleComplexMatrix Wn = new DoubleComplexMatrix(W0).multiply(j).expElementWise();

    DoubleComplexMatrix X = j.createZeroGrid(Y.getRowSize(), Y.getColumnSize());
    for (int k = 0; k <= size - 1; k++) {
      X.setColumnVector(k + 1, new DoubleComplexMatrix(Y).multiply(Wn.powerElementWise(k)));
    }

    return X.divide(size);
  }

  /**
   * 逆離散フーリエ変換の結果をプロットする
   * 
   * @param Y データ
   * @return Gnuplot
   * @throws IOException gnuplotプロセスを起動できない場合
   */
  @SuppressWarnings("nls")
  public static Gnuplot plot(DoubleMatrix Y) throws IOException {
    DoubleComplexMatrix X = idft(Y);
    Gnuplot gp = new Gnuplot();
    Canvas canvas = gp.createCanvas();
    canvas.setXLabel("time");
    canvas.setYLabel("");
    canvas.setTitle("idft plot");
    canvas.plot(X.getRealPart());
    return gp;
  }

  /**
   * 逆離散フーリエ変換の結果をプロットする
   * 
   * @param Y データ
   * @param size データの個数
   * @return Gnuplot
   * @throws IOException gnuplotプロセスを起動できない場合
   */
  @SuppressWarnings("nls")
  public static Gnuplot plot(DoubleMatrix Y, int size) throws IOException {
    DoubleComplexMatrix X = idft(Y, size);
    Gnuplot gp = new Gnuplot();
    Canvas canvas = gp.createCanvas();
    canvas.setXLabel("time");
    canvas.setYLabel("");
    canvas.setTitle("idft plot");
    canvas.plot(X.getRealPart());
    return gp;
  }

}