ImportSource.java
/*
* Created on 2007/06/08
* Copyright (C) 2007 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 koga
* @version $Revision: 1.9 $, 2007/06/08
* @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 ImportSource<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 ContinuousSource<RS,RM,CS,CM> implements Importer {
/** データ */
private RM data;
/** 最後に出力した時刻の番号 */
private int last = 1;
/**
* 新しく生成された<code>ImportSource</code>オブジェクトを初期化します。
* @param sunit unit of scalar
*/
public ImportSource(RS sunit) {
super(-1, sunit);
}
/**
* データを設定します。
*
* @param data データ
*/
public void setData(final RM data) {
if (data == null) {
this.data = null;
this.last = 1;
return;
}
checkDataMatrix(data);
this.data = data.createClone();
this.last = 1;
setOutputSize(this.data.getRowSize() - 1);
}
/**
* 行列の検査を行います。
*
* @param m 行列
* @throws IllegalArgumentException 入力行列の行数、列数が足りない場合、または時間行が単調増加ではない場合
*/
private void checkDataMatrix(RM m) {
if (m.getRowSize() < 2) throw new IllegalArgumentException(Messages.getString("ImportSource.0")); //$NON-NLS-1$
if (m.getColumnSize() == 0) throw new IllegalArgumentException(Messages.getString("ImportSource.1")); //$NON-NLS-1$
RS oldValue = m.getElement(1, 1);
for (int i = 2; i <= m.getColumnSize(); i++) {
final RS newValue = m.getElement(1, i);
if (oldValue.isGreaterThan(newValue)) throw new IllegalArgumentException(Messages.getString("ImportSource.2")); //$NON-NLS-1$
oldValue = newValue;
}
}
/**
* {@inheritDoc}
*/
@Override
public RM outputEquation(final RS t) {
int previous = -1;
int next = -1;
final int dataSize = this.data.getColumnSize();
if (t.isLessThan(this.data.getElement(1, this.last))) {
for (int i = this.last; 1 <= i; i--) {
if (this.data.getElement(1, i).isLessThanOrEquals(t)) {
previous = i;
next = i + 1;
this.last = next;
break;
}
}
if (previous == -1 || next == -1) {
final RS previousTime = this.data.getElement(2);
final RS nextTime = this.data.getElement(1);
final RM previousData = this.data.getSubMatrix(2, this.data.getRowSize(), 2, 2);
final RM nextData = this.data.getSubMatrix(2, this.data.getRowSize(), 1, 1);
return previousData.add(nextData.subtract(previousData).multiply(t.subtract(previousTime).divide(nextTime.subtract(previousTime))));
}
} else {
for (int i = this.last; i <= dataSize; i++) {
if (t.isLessThanOrEquals(this.data.getElement(1, i))) {
previous = i - 1;
next = i;
this.last = previous;
break;
}
}
if (previous == -1 || next == -1) {
final RS previousTime = this.data.getElement(dataSize - 1);
final RS nextTime = this.data.getElement(dataSize);
final RM previousData = this.data.getSubMatrix(2, this.data.getRowSize(), dataSize - 1, dataSize - 1);
final RM nextData = this.data.getSubMatrix(2, this.data.getRowSize(), dataSize, dataSize);
return previousData.add(nextData.subtract(previousData).multiply(t.subtract(previousTime).divide(nextTime.subtract(previousTime))));
}
}
if (next == 1) {
this.last = 1;
return this.data.getSubMatrix(2, this.data.getRowSize(), 1, 1);
}
if (previous == dataSize) {
this.last = dataSize;
return this.data.getSubMatrix(2, this.data.getRowSize(), dataSize, dataSize);
}
final RS previousTime = this.data.getElement(1, previous);
final RS nextTime = this.data.getElement(1, next);
final RM previousData = this.data.getSubMatrix(2, this.data.getRowSize(), previous, previous);
final RM nextData = this.data.getSubMatrix(2, this.data.getRowSize(), next, next);
return previousData.add(nextData.subtract(previousData).multiply(t.subtract(previousTime).divide(nextTime.subtract(previousTime))));
}
/**
* @see org.mklab.tool.control.system.source.Importer#isActive()
*/
public boolean isActive() {
if (this.data != null) {
return true;
}
return false;
}
/**
* @see org.mklab.tool.control.system.continuous.BaseContinuousStaticSystem#initialize()
*/
@Override
public void initialize() {
super.initialize();
this.last = 1;
}
/**
* @see org.mklab.tool.control.system.SystemOperator#equals(java.lang.Object)
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!super.equals(o)) {
return false;
}
if (o == null) {
return false;
}
if (o.getClass() != getClass()) {
return false;
}
ImportSource<RS,RM,CS,CM> castedObj = (ImportSource<RS,RM,CS,CM>)o;
return ((this.data == null ? castedObj.data == null : this.data.equals(castedObj.data)) && (this.last == castedObj.last));
}
/**
* @see org.mklab.tool.control.system.SystemOperator#hashCode()
*/
@Override
public int hashCode() {
int hashCode = super.hashCode();
hashCode = 31 * hashCode + (this.data == null ? 0 : this.data.hashCode());
hashCode = 31 * hashCode + this.last;
return hashCode;
}
}