Cceps.java

/*
 * $Id: Cceps.java,v 1.31 2008/03/15 00:23:44 koga Exp $
 * 
 * Copyright (C) 2004 Koga Laboratory. All rights reserved.
 */
package org.mklab.tool.signal;

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.matrix.Angle;
import org.mklab.tool.matrix.Unwrap;


/**
 * 複素ケプストラムを求めるクラスです。
 * 
 * <p>Complex cepstrum
 * 
 * @author koga
 * @version $Revision: 1.31 $
 * @see org.mklab.tool.signal.Rceps
 */
public class Cceps {

  /**
   * <code>x</code> の複素ケプストラムを返します。
   * 
   * @param x データ
   * @return (複素ケプストラム) complex cepstrum
   */
  public static DoubleMatrix cceps(DoubleMatrix x) {
    DoubleNumber unit = x.getElement(1, 1);
    DoubleComplexNumber j = new DoubleComplexNumber(0,1);
    int length = x.length();
    int n2 = (int)(fix((length + 1) / 2.0));

    DoubleComplexMatrix X = x.fft();
    DoubleMatrix Y = Unwrap.unwrap(Angle.angle(X));
    DoubleNumber pi = unit.createPI();
    Y = Y.subtract(new DoubleMatrix(IntMatrix.series(0, length - 1)).multiply(Y.getElement(n2 + 1).divide(pi).fix().multiply(pi).divide(n2 + 1)));

    DoubleMatrix xc = X.absElementWise().logElementWise().add(new DoubleComplexMatrix(Y).multiply(j)).logElementWise().getRealPart();
    return xc;
  }

  /**
   * 丸めます。
   * 
   * @param d 丸める値
   * @return 丸められた結果
   */
  private static double fix(double d) {
    if (d > 0) return Math.floor(d);
    return Math.ceil(d);
  }

}