Square.java

/*
 * $Id: Square.java,v 1.15 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.DoubleMatrix;
import org.mklab.nfc.matrix.IntMatrix;
import org.mklab.nfc.scalar.DoubleNumber;


/**
 * 矩形信号を生成するクラスです。
 * 
 * <p> Square wave
 * 
 * @author koga
 * @version $Revision: 1.15 $
 * @see org.mklab.tool.signal.Sawtooth
 */
public class Square {

  /**
   * 時刻の列<code>t</code>に対して、周期<code>2*PI</code> の矩形波の信号を返します。
   * 
   * @param t 時刻の列
   * @return 矩形信号 (square wave)
   */
  public static DoubleMatrix square(DoubleMatrix t) {
    double duty = 50.0;
    return square(t, duty);
  }

  /**
   * 指定されたデューティー周期の矩形波信号を返します。
   * 
   * @param t 時刻の列
   * @param duty 正の値となる時間のパーセンテージ
   * @return 矩形信号 (square wave)
   */
  @SuppressWarnings("nls")
  public static DoubleMatrix square(DoubleMatrix t, double duty) {
    DoubleNumber unit = t.getElement(1, 1).createUnit();
    DoubleNumber pi = unit.createPI();

    DoubleNumber w0 = pi.multiply(2).multiply(duty).divide(100);

    // Normalized t
    DoubleMatrix nt = t.remainderElementWise(pi.multiply(2));
    IntMatrix idx = nt.compareElementWise(".>", w0).orElementWise(nt.compareElementWise(".<", w0.subtract(pi.multiply(2)))).find();
    DoubleMatrix no = t.createZero();
    no.setSubVector(idx, t.createOnes(1, idx.length()));
    IntMatrix idx2 = t.compareElementWise(".<", 0).find();
    DoubleMatrix ne = t.createZero();
    ne.setSubVector(idx2, t.createOnes(1, idx2.length()));
    DoubleMatrix wv = ne.add(no).add(t.createOnes()).remainderElementWise(unit.multiply(2)).multiply(2).subtractElementWise(1);
    return wv;
  }

}