FixedRateAsynchronousSource.java
/*
* Created on 2010/01/04
* Copyright (C) 2010 Koga Laboratory. All rights reserved.
*
*/
package org.mklab.tool.control.system.source;
import org.mklab.nfc.matrix.ComplexNumericalMatrix;
import org.mklab.nfc.matrix.RealNumericalMatrix;
import org.mklab.nfc.scalar.ComplexNumericalScalar;
import org.mklab.nfc.scalar.RealNumericalScalar;
/**
* 等間隔のサンプリングを行うソースです。
*
* @author Yuhi Ishikura
* @version $Revision$, 2010/01/04
* @param <RS> type of real scalar
* @param <RM> type of real matrix
* @param <CS> type of complex scalar
* @param <CM> type of complex matrix
*/
public abstract class FixedRateAsynchronousSource<RS extends RealNumericalScalar<RS,RM,CS,CM>, RM extends RealNumericalMatrix<RS,RM,CS,CM>, CS extends ComplexNumericalScalar<RS,RM,CS,CM>, CM extends ComplexNumericalMatrix<RS,RM,CS,CM>> extends AsynchronousSource<RS,RM,CS,CM> {
/** 全出力データです。 */
private RS[] outputData;
/** 出力データ配列中の次に記録するインデックスです。 */
private int outputIndex;
/** 次に記録するデータの時間です。 */
private RS time;
/** データの時間の間隔、サンプリングインターバルです。 */
private RS interval;
/**
* {@link FixedRateAsynchronousSource}オブジェクトを構築します。
*
* @param size サイズ
* @param interval データの時間の間隔、サンプリングインターバル
* @param sunit unit of scalar
*/
public FixedRateAsynchronousSource(int size, RS interval, RS sunit) {
super(1, sunit);
this.outputData = sunit.createArray(size);
this.interval = interval;
}
/**
* {@inheritDoc}
*/
@Override
protected final RM getOutput(RS t) {
if (isReadyFor(t) == false) {
throw new IllegalStateException(Messages.getString("FixedRateAsynchronousSource.1")); //$NON-NLS-1$
}
final int index = (int)t.divide( this.interval).toDouble();
if (index >= this.outputData.length) {
throw new IndexOutOfBoundsException(Messages.getString("FixedRateAsynchronousSource.0")); //$NON-NLS-1$
}
RS[] out =this.sunit.createArray(1);
out[0]= this.outputData[index];
return this.sunit.createGrid(out);
}
/**
* {@inheritDoc}
*/
@Override
protected final boolean isReadyFor(RS t) {
return t.isLessThan(this.time);
}
/**
* 出力データがいっぱいであるかを調べます。
*
* @return これ以上記録できない場合はtrue,そうでなければfalse
*/
protected final boolean isOutputDataFilled() {
return this.outputIndex >= this.outputData.length;
}
/**
* 出力を追加します。
*
* @param output 出力
*/
protected final void publish(RS output) {
if (isOutputDataFilled()) {
throw new IllegalStateException();
}
this.outputData[this.outputIndex] = output;
this.outputIndex++;
this.time = this.time.add(this.interval);
bufferChanged();
}
}