Detrend.java

/*
 * $Id: Detrend.java,v 1.11 2008/04/06 02:16:45 koga Exp $
 * 
 * Copyright (C) 2004 Koga Laboratory. All rights reserved.
 */
package org.mklab.tool.signal;

import org.mklab.nfc.matrix.DoubleMatrix;
import org.mklab.nfc.matrix.IntMatrix;
import org.mklab.nfc.scalar.DoubleNumber;
import org.mklab.tool.matrix.Makecolv;


/**
 * 線形トレンドを除去した信号を求めるクラスです。
 * 
 * <p> Remove a linear trend
 * 
 * @author koga
 * @version $Revision: 1.11 $
 * @see org.mklab.nfc.matrix.Matrix#meanRowWise
 * @see org.mklab.nfc.matrix.Matrix#meanColumnWise
 */
public class Detrend {

  /**
   * <code>X</code>から線形トレンドを除いたデータを返します。
   * 
   * @param data データ
   * @return 線形トレンドを除去した信号 (signal whose linear trend are removed)
   */
  public static DoubleMatrix detrend(DoubleMatrix data) {
    return detrendRowWise(data);
  }

  /**
   * <code>X</code>から平均を除く。
   * 
   * @param data データ
   * @param zeroMean 平均値を除くならば1
   * @return 線形トレンドを除去した信号 (signal whose mean are removed)
   */
  public static DoubleMatrix detrend(DoubleMatrix data, int zeroMean) {
    return detrendRowWise(data, zeroMean);
  }

  /**
   * 行列の行毎にトレンドを除く。
   * 
   * @param data データ
   * @return signal whose linear trend are removed
   */
  public static DoubleMatrix detrendRowWise(DoubleMatrix data) {
    return detrendColumnWise(data.transpose()).transpose();
  }

  /**
   * 行列の行毎に平均を除く。
   * 
   * @param data データ
   * @param zeroMean 平均値を除くならば1
   * @return signal whose mean are removed
   */
  public static DoubleMatrix detrendRowWise(DoubleMatrix data, int zeroMean) {
    return detrendColumnWise(data.transpose(), zeroMean).transpose();
  }

  /**
   * 行列の列毎にトレンドを除きます。
   * 
   * @param X データ
   * @return signal whose linear trend are removed
   */
  public static DoubleMatrix detrendColumnWise(DoubleMatrix X) {
    int tr = 1;
    return detrendColumnWise(X, tr);
  }

  /**
   * 行列の列毎に平均を除きます。
   * 
   * @param data データ
   * @param zeroMean 平均値を除くならば1
   * @return signal whose mean are removed
   */
  public static DoubleMatrix detrendColumnWise(DoubleMatrix data, int zeroMean) {
    DoubleMatrix X = Makecolv.makecolv(data);
    DoubleNumber unit = X.getElement(1, 1).createUnit();

    int m = X.getRowSize();

    DoubleMatrix Y;
    if (zeroMean == 0) { // Remove the mean
      Y = X.subtract(X.createOnes(m, 1).multiply(X.transpose().meanRowWise()));
    } else { // Remove line fit
      DoubleMatrix A = new DoubleMatrix(IntMatrix.series(1, m)).transpose().divide(unit.multiply(m)).appendRight(X.createOnes(m, 1));
      Y = X.subtract(A.multiply(A.leftDivide(X)));
    }

    if (data.getRowSize() == 1) {
      Y = Y.transpose();
    }

    return Y;
  }

}