ConstantSystem.java
/*
* $Id: ConstantSystem.java,v 1.41 2008/07/16 03:51:37 koga Exp $
*
* Copyright (C) 2004 Koga Laboratory. All rights reserved.
*
*/
package org.mklab.tool.control.system.math;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.mklab.nfc.matrix.ComplexNumericalMatrix;
import org.mklab.nfc.matrix.RealNumericalMatrix;
import org.mklab.nfc.rpn.AbstractExpressionProcessor;
import org.mklab.nfc.rpn.AddOperator;
import org.mklab.nfc.rpn.DoubleOperandOperator;
import org.mklab.nfc.rpn.ExpressionProcessor;
import org.mklab.nfc.rpn.InverseOperator;
import org.mklab.nfc.rpn.MultiplyOperator;
import org.mklab.nfc.rpn.ReversePolishNotationOperand;
import org.mklab.nfc.rpn.ReversePolishNotationOperator;
import org.mklab.nfc.rpn.ReversePolishNotationSymbol;
import org.mklab.nfc.rpn.SingleOperandOperator;
import org.mklab.nfc.scalar.ComplexNumericalScalar;
import org.mklab.nfc.scalar.RealNumericalScalar;
import org.mklab.tool.control.LinearSystem;
import org.mklab.tool.control.LinearSystemFactory;
import org.mklab.tool.control.system.LinearSystemOperator;
import org.mklab.tool.control.system.SymbolicOperator;
import org.mklab.tool.control.system.continuous.BaseContinuousStaticSystem;
import org.mklab.tool.control.system.continuous.ContinuousLinearDynamicSystem;
/**
* 定数システムを表わすクラスです。
*
* @author Koga Laboratory
* @version $Revision: 1.41 $, 2004/11/12
* @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 class ConstantSystem<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 BaseContinuousStaticSystem<RS,RM,CS,CM> implements LinearSystemOperator<RS,RM,CS,CM>, SymbolicOperator, ReversePolishNotationOperand<RS,RM> {
/** システム */
private LinearSystem<RS,RM,CS,CM> gainSystem;
/** 数式 */
private String expression = ""; //$NON-NLS-1$
/** 1個の項として扱えるシステムならばtrue */
private boolean singleTerm = true;
/** シンボルのスタック */
private List<ReversePolishNotationSymbol<RS,RM>> symbolStack = new ArrayList<>();
/** タグ */
private String tag;
/** 状態空間実現を求めるならばtrue */
private static boolean requiringABCD = false;
/** マイナスの項ならばtrue */
private boolean isNegative = false;
/** 変数として扱うならtrue */
private boolean isVariable = false;
/**
* 新しく生成された<code>ConstantSystem</code>オブジェクトを初期化します。
*
* @param inputSize 入力数
* @param outputSize 出力数
* @param sunit unit of scalar
*/
public ConstantSystem(final int inputSize, final int outputSize, RS sunit) {
super(inputSize, outputSize, sunit);
setHasDirectFeedthrough(true);
setLinear(true);
this.tag = "" + hashCode(); //$NON-NLS-1$
this.symbolStack.add(this);
}
/**
* 新しく生成された<code>ConstantSystem</code>オブジェクトを初期化します。
*
* @param gain 定数ゲイン行列
*/
public ConstantSystem(final RM gain) {
this(gain.getColumnSize(), gain.getRowSize(), gain.getElement(1,1).createUnit());
this.gainSystem = LinearSystemFactory.createConstant(gain);
final int inputSize = gain.getColumnSize();
final int outputSize = gain.getRowSize();
this.expression = "ConstantSystem(" + inputSize + " inputs, " + outputSize + " outputs)"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
/**
* 定数ゲイン行列を設定します。
*
* @param gain 定数ゲイン行列
*/
public void setGain(final RM gain) {
this.gainSystem = LinearSystemFactory.createConstant(gain);
}
/**
* {@inheritDoc}
*/
@Override
public RM outputEquation( final RS t, final RM u) {
return this.gainSystem.getD().multiply(u);
}
/**
* 単位システムであるか判定します。
*
* @return 単位システムならtrue、そうでなければfalse
*/
public boolean isUnit() {
final RM K = this.gainSystem.getD();
return K.getRowSize() == K.getColumnSize() && K.isUnit();
}
/**
* 負の単位システムであるか判定します。
*
* @return 負の単位システムならtrue、そうでなければfalse
*/
public boolean isNegativeUnit() {
final RM K = this.gainSystem.getD();
return K.getRowSize() == K.getColumnSize() && K.unaryMinus().isUnit();
}
/**
* 二つのシステムの和システムを返します。
*
* @param opponent 足すシステム
* @return 結合したシステム
*/
public ConstantSystem<RS,RM,CS,CM> add(final ConstantSystem<RS,RM,CS,CM> opponent) {
final RM gain = this.gainSystem.getD().add(opponent.gainSystem.getD());
final ConstantSystem<RS,RM,CS,CM> constantSystem = new ConstantSystem<>(gain);
constantSystem.setVariable(this.isVariable || opponent.isVariable);
if (requiringABCD == false) {
return constantSystem;
}
constantSystem.setSymbolStack(this.createSymbolStack(opponent, new AddOperator<RS,RM>()));
return constantSystem;
}
/**
* 二つのシステムの差システムを返します。
*
* @param opponent 引くシステム
* @return 結合したシステム
*/
public ConstantSystem<RS,RM,CS,CM> subtract(final ConstantSystem<RS,RM,CS,CM> opponent) {
final ConstantSystem<RS,RM,CS,CM> constantSystem = new ConstantSystem<>(this.gainSystem.getD().subtract(opponent.gainSystem.getD()));
constantSystem.setVariable(this.isVariable || opponent.isVariable);
if (requiringABCD == false) {
return constantSystem;
}
constantSystem.setSubtractiveExpression(this, opponent);
return constantSystem;
}
/**
* 二つのシステムの差を表す数式を設定します。
* TODO(koga)
* @param first 第一項
* @param second 第二項
*/
private void setSubtractiveExpression(final ConstantSystem<RS,RM,CS,CM> first, final ConstantSystem<RS,RM,CS,CM> second) {
String firstExpression = first.getMultipliedSystem().getExpression();
if (first.isSingleTerm() == false) {
firstExpression = "(" + firstExpression + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
String secondExpression = second.getMultipliedSystem().getExpression();
if (second.isSingleTerm() == false) {
secondExpression = "(" + secondExpression + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
if (second.isZero() || second.gainSystem.getD().isZero()) {
setExpression(firstExpression);
} else if (first.isZero() || first.gainSystem.getD().isZero()) {
setExpression("- " + secondExpression); //$NON-NLS-1$
} else {
setExpression(firstExpression + " - " + secondExpression); //$NON-NLS-1$
}
setSingleTerm(false);
}
/**
* 二つのシステムの積システムを返します。
*
* @param opponent 掛けるシステム
* @return 結合したシステム
*/
public ConstantSystem<RS,RM,CS,CM> multiply(final ConstantSystem<RS,RM,CS,CM> opponent) {
if (opponent instanceof UnitSystem) {
return this;
}
final RM gain = this.gainSystem.getD().multiply(opponent.gainSystem.getD());
final ConstantSystem<RS,RM,CS,CM> constantSystem = new ConstantSystem<>(gain);
constantSystem.setVariable(this.isVariable || opponent.isVariable);
if (requiringABCD == false) {
return constantSystem;
}
constantSystem.setSymbolStack(this.createSymbolStack(opponent, new MultiplyOperator<RS,RM>()));
return constantSystem;
}
/**
* (ネガティブ)フィードバック結合したシステムを返します。
*
* @param opponent フィードバック成分
* @return 結合したシステム
*/
public ConstantSystem<RS,RM,CS,CM> feedback(final ConstantSystem<RS,RM,CS,CM> opponent) {
return feedback(opponent, true);
}
/**
* フィードバック結合したシステムを返します。
*
* @param opponent フィードバック要素
* @param negativeFeedback ネガティブフィードバックならばtrue、そうでなければfalse
* @return 結合したシステム
*/
public ConstantSystem<RS,RM,CS,CM> feedback(final ConstantSystem<RS,RM,CS,CM> opponent, final boolean negativeFeedback) {
final RM gain1 = this.gainSystem.getD();
final RM gain2 = opponent.gainSystem.getD();
if (negativeFeedback) {
ConstantSystem<RS,RM,CS,CM> constantSystem = new ConstantSystem<>(this.sunit.createUnitGrid(gain1.getRowSize()).add(gain1.multiply(gain2)).leftDivide(gain1));
constantSystem.setVariable(this.isVariable || opponent.isVariable);
return constantSystem;
}
ConstantSystem<RS,RM,CS,CM> constantSystem = new ConstantSystem<>(this.sunit.createUnitGrid(gain1.getRowSize()).subtract(gain1.multiply(gain2)).leftDivide(gain1));
constantSystem.setVariable(this.isVariable || opponent.isVariable);
return constantSystem;
}
/**
* 定数ゲイン行列を返します。
*
* @return 定数ゲイン行列
*/
public RM getGain() {
return this.gainSystem.getD();
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#getLinearSystem()
*/
@Override
public LinearSystem<RS,RM,CS,CM> getLinearSystem() {
return this.gainSystem;
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#setLinearSystem(org.mklab.tool.control.LinearSystem)
*/
public void setLinearSystem(final LinearSystem<RS,RM,CS,CM> system) {
this.gainSystem = system;
setInputSize(system.getInputSize());
setOutputSize(system.getOutputSize());
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#hasVariableA()
*/
public boolean hasVariableA() {
return this.isVariable;
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#hasVariableB()
*/
public boolean hasVariableB() {
return this.isVariable;
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#hasVariableC()
*/
public boolean hasVariableC() {
return this.isVariable;
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#hasVariableD()
*/
public boolean hasVariableD() {
return this.isVariable;
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#hasVariableE()
*/
public boolean hasVariableE() {
return this.isVariable;
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#setHasVariableA(boolean)
*/
public void setHasVariableA( final boolean hasVariableA) {
// nothing to do;
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#setHasVariableB(boolean)
*/
public void setHasVariableB( final boolean hasVariableB) {
// nothing to do;
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#setHasVariableC(boolean)
*/
public void setHasVariableC( final boolean hasVariableC) {
// nothing to do;
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#setHasVariableD(boolean)
*/
public void setHasVariableD(final boolean hasVariableD) {
this.isVariable = hasVariableD;
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#setHasVariableE(boolean)
*/
public void setHasVariableE( final boolean hasVariableE) {
// nothing to do;
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#getA()
*/
public RM getA() {
return this.gainSystem.getA();
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#getB()
*/
public RM getB() {
return this.gainSystem.getB();
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#getC()
*/
public RM getC() {
return this.gainSystem.getC();
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#getD()
*/
public RM getD() {
return this.gainSystem.getD();
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#getE()
*/
public RM getE() {
return this.gainSystem.getE();
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#add(org.mklab.tool.control.system.LinearSystemOperator)
*/
public LinearSystemOperator<RS,RM,CS,CM> add(final LinearSystemOperator<RS,RM,CS,CM> opponent) {
return add(opponent, true);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#add(org.mklab.tool.control.system.LinearSystemOperator, boolean)
*/
public LinearSystemOperator<RS,RM,CS,CM> add(final LinearSystemOperator<RS,RM,CS,CM> opponent, final boolean simplify) {
return new ContinuousLinearDynamicSystem<>(this.gainSystem.add(opponent.getLinearSystem(), simplify), this.sunit);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#subtract(org.mklab.tool.control.system.LinearSystemOperator)
*/
public LinearSystemOperator<RS,RM,CS,CM> subtract(final LinearSystemOperator<RS,RM,CS,CM> opponent) {
return subtract(opponent, true);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#subtract(org.mklab.tool.control.system.LinearSystemOperator, boolean)
*/
public LinearSystemOperator<RS,RM,CS,CM> subtract(final LinearSystemOperator<RS,RM,CS,CM> opponent, final boolean simplify) {
return new ContinuousLinearDynamicSystem<>(this.gainSystem.subtract(opponent.getLinearSystem(), simplify), this.sunit);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#multiply(org.mklab.tool.control.system.LinearSystemOperator)
*/
public LinearSystemOperator<RS,RM,CS,CM> multiply(final LinearSystemOperator<RS,RM,CS,CM> system) {
return multiply(system, true);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#multiply(org.mklab.tool.control.system.LinearSystemOperator, boolean)
*/
public LinearSystemOperator<RS,RM,CS,CM> multiply(final LinearSystemOperator<RS,RM,CS,CM> opponent, final boolean simplify) {
return new ContinuousLinearDynamicSystem<>(this.gainSystem.multiply(opponent.getLinearSystem(), simplify), this.sunit);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#feedback(org.mklab.tool.control.system.LinearSystemOperator)
*/
public LinearSystemOperator<RS,RM,CS,CM> feedback(final LinearSystemOperator<RS,RM,CS,CM> system) {
return feedback(system, true, true);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#feedback(org.mklab.tool.control.system.LinearSystemOperator, boolean)
*/
public LinearSystemOperator<RS,RM,CS,CM> feedback(final LinearSystemOperator<RS,RM,CS,CM> opponent, final boolean negativeFeedback) {
return feedback(opponent, negativeFeedback, true);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#feedback(org.mklab.tool.control.system.LinearSystemOperator, boolean, boolean)
*/
public LinearSystemOperator<RS,RM,CS,CM> feedback(final LinearSystemOperator<RS,RM,CS,CM> opponent, final boolean negativeFeedback, final boolean simplify) {
return new ContinuousLinearDynamicSystem<>(this.gainSystem.feedback(opponent.getLinearSystem(), negativeFeedback, simplify), this.sunit);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#unaryMinus()
*/
public ConstantSystem<RS,RM,CS,CM> unaryMinus() {
// final ConstantSystem<RS,RM,CS,CM> constantSystem = new ConstantSystem<RS,RM,CS,CM>(this.gainSystem.getD().unaryMinus());
// constantSystem.setVariable(this.isVariable);
//
// if (requiringABCD == false) {
// return constantSystem;
// }
// constantSystem.setUnaryMinusExpression(this);
// return constantSystem;
return this.multiply(new NegativeUnitSystem<>(this.gainSystem.getD().getColumnSize(), this.sunit));
}
/**
* 符号を反転した数式を設定します。
*
* @param system 対象となるシステム
*/
protected void setUnaryMinusExpression(final ConstantSystem<RS,RM,CS,CM> system) {
if (system.isZero() || system.gainSystem.getD().isZero()) {
setExpression(""); //$NON-NLS-1$
} else {
// setExpression(system.getExpression());
setTag(system.getTag());
setNegative(!system.isNegative);
}
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#unityFeedback()
*/
public ConstantSystem<RS,RM,CS,CM> unityFeedback() {
return unityFeedback(true, true);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#unityFeedback(boolean)
*/
public ConstantSystem<RS,RM,CS,CM> unityFeedback(final boolean negativeFeedback) {
return unityFeedback(negativeFeedback, true);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#unityFeedback(boolean, boolean)
*/
public ConstantSystem<RS,RM,CS,CM> unityFeedback(final boolean negativeFeedback, final boolean simplify) {
final RM K = this.gainSystem.getD();
if (negativeFeedback) {
ConstantSystem<RS,RM,CS,CM> constantSystem = new ConstantSystem<>(this.sunit.createUnitGrid(K.getRowSize()).add(K).leftDivide(K));
constantSystem.setVariable(this.isVariable);
return constantSystem;
}
ConstantSystem<RS,RM,CS,CM> constantSystem = new ConstantSystem<>(this.sunit.createUnitGrid(K.getRowSize()).subtract(K).leftDivide(K));
constantSystem.setVariable(this.isVariable);
return constantSystem;
}
/**
* 単一フィードバック系がwell-posedであるか判定します。
*
* <p>(I + G)または(I - G)が正則であるか判定します。
*
* @param negativeFeedback 負フィードバックならばtrue、正フィードバックならばfalse
* @return 単一フィードバック系がwell-posedならばtrue、そうでなければfalse
*/
public boolean isUnityFeedbackWellPosed(final boolean negativeFeedback) {
final RM K = getGain();
if (K.getRowSize() != K.getColumnSize()) {
return false;
}
if (negativeFeedback) {
return this.sunit.createUnitGrid(K.getRowSize()).add(K).isFullRank();
}
return this.sunit.createUnitGrid(K.getRowSize()).subtract(K).isFullRank();
}
/**
* 単一フィードバック系の感度関数「(I + K)~」(負フィードバック)、「(I - K)~」(正フィードバック)を返します。
*
* @param negativeFeedback 負フィードバックならばtrue、正フィードバックならばfalse
* @return 単一フィードバック系の感度関数「(I + K)~」(負フィードバック)、「(I - K)~」(正フィードバック)
*/
public ConstantSystem<RS,RM,CS,CM> getSensitivityOfUnityFeedback(final boolean negativeFeedback) {
final RM K = getGain();
final RM gain = negativeFeedback ? this.sunit.createUnitGrid(K.getRowSize()).add(K).inverse() : this.sunit.createUnitGrid(K.getRowSize()).subtract(K).inverse();
final ConstantSystem<RS,RM,CS,CM> constantSystem = new ConstantSystem<>(gain);
constantSystem.setVariable(this.isVariable);
if (requiringABCD == false) {
return constantSystem;
}
if (isZero() || this.gainSystem.getD().isZero()) {
return new UnitSystem<>(getInputSize(), this.sunit);
}
final ConstantSystem<RS,RM,CS,CM> system = negativeFeedback ? new UnitSystem<>(constantSystem.getInputSize(), this.sunit).add(this) : new UnitSystem<>(constantSystem.getInputSize(), this.sunit).add(this.multiply(new NegativeUnitSystem<>(
this.getInputSize(), this.sunit)));
system.setVariable(this.isVariable);
system.setSingleTerm(false);
return (system).inverse();
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#inverse()
*/
public ConstantSystem<RS,RM,CS,CM> inverse() {
final RM gain = getGain();
gain.singularValue();
final boolean stopIfSingular = true;
final RM inversGain = gain.inverse(gain.frobNorm().multiply(this.sunit.getMachineEpsilon()), stopIfSingular);
final ConstantSystem<RS,RM,CS,CM> constantSystem = (ConstantSystem<RS,RM,CS,CM>)this.createOperand(inversGain);
constantSystem.setVariable(this.isVariable);
constantSystem.getSymbolStack().remove(0);
constantSystem.addSymbol(this);
constantSystem.addSymbol(new InverseOperator<RS,RM>());
return constantSystem;
}
/**
* @see org.mklab.tool.control.system.SymbolicOperator#getExpression()
*/
public String getExpression() {
return this.expression;
}
/**
* @see org.mklab.tool.control.system.SymbolicOperator#setExpression(java.lang.String)
*/
public void setExpression(final String expression) {
this.expression = expression;
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#getTag()
*/
public String getTag() {
return this.tag;
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#setTag(java.lang.String)
*/
public void setTag(final String tag) {
this.tag = tag;
}
/**
* 状態空間を求めるから判定します。
*
* @return 状態空間を求めるならばtrue、そうでなければfalse
*/
public static boolean isRequiringABCD() {
return requiringABCD;
}
/**
* 状態空間を求めるか設定します。
*
* @param reruiringABCD 状態空間を求めるならばtrue、そうでなければfalse
*/
public static void setRequiringABCD(final boolean reruiringABCD) {
ConstantSystem.requiringABCD = reruiringABCD;
}
/**
* 1個の項からなるシステムであるか判定します。
*
* @return 1個の項からなるシステムならばtrue、そうでなければfalse
*/
public boolean isSingleTerm() {
return this.singleTerm;
}
/**
* 1個の項からなるシステムであるかを設定します。
*
* @param singleTerm 1個の項からなるシステムならばtrue、そうでなければfalse
*/
public void setSingleTerm(final boolean singleTerm) {
this.singleTerm = singleTerm;
}
/**
* @see org.mklab.tool.control.system.SystemOperator#clone()
*/
@Override
public ConstantSystem<RS,RM,CS,CM> clone() {
final ConstantSystem<RS,RM,CS,CM> inst = (ConstantSystem<RS,RM,CS,CM>)super.clone();
if (this.gainSystem != null) {
inst.gainSystem = (LinearSystem<RS,RM,CS,CM>)this.gainSystem.clone();
}
if (this.expression == null) {
inst.expression = null;
} else {
inst.expression = new String(this.expression);
}
inst.singleTerm = this.singleTerm;
inst.tag = this.tag;
inst.symbolStack = Collections.unmodifiableList(this.symbolStack);
inst.isNegative = this.isNegative;
inst.isVariable = this.isVariable;
return inst;
}
/**
* @see org.mklab.tool.control.system.SystemOperator#hashCode()
*/
@Override
public int hashCode() {
int hashCode = super.hashCode();
hashCode = 31 * hashCode + (this.gainSystem == null ? 0 : this.gainSystem.hashCode());
hashCode = 31 * hashCode + (this.expression == null ? 0 : this.expression.hashCode());
hashCode = 31 * hashCode + (this.singleTerm ? 1231 : 1237);
hashCode = 31 * hashCode + (this.tag == null ? 0 : this.tag.hashCode());
hashCode = 31 * hashCode + (requiringABCD ? 1231 : 1237);
return hashCode;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#getSignedExpression()
*/
public String getSignedExpression() {
return this.isNegative() ? "-" + this.getExpression() : this.getExpression(); //$NON-NLS-1$
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#getParsedOperand()
*/
public ReversePolishNotationOperand<RS,RM> getParsedOperand() {
String composedExpression = ""; //$NON-NLS-1$
for (final ReversePolishNotationSymbol<RS,RM> symbol : this.getSymbolStack()) {
final String singleExpression = ((ReversePolishNotationOperand<RS,RM>)symbol).getExpression();
if (composedExpression.equals("")) { //$NON-NLS-1$
//if (this.isNegative()) {
if (((ReversePolishNotationOperand<RS,RM>)symbol).isNegative()) {
composedExpression = ((ReversePolishNotationOperand<RS,RM>)symbol).getSignedExpression();
} else {
composedExpression = singleExpression;
}
continue;
}
if (((ReversePolishNotationOperand<RS,RM>)symbol).isNegative()) {
composedExpression = composedExpression + " - " + singleExpression; //$NON-NLS-1$
} else {
composedExpression = composedExpression + " + " + singleExpression; //$NON-NLS-1$
}
}
setExpression(composedExpression);
return this;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#setSymbolStack(java.util.List)
*/
public void setSymbolStack(final List<ReversePolishNotationSymbol<RS,RM>> reversePolishNotationSymbolStack) {
this.symbolStack = reversePolishNotationSymbolStack;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#getSymbolStack()
*/
public List<ReversePolishNotationSymbol<RS,RM>> getSymbolStack() {
return this.symbolStack;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#addSymbol(org.mklab.nfc.rpn.ReversePolishNotationSymbol)
*/
public void addSymbol(final ReversePolishNotationSymbol<RS,RM> symbol) {
this.symbolStack.add(symbol);
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#addSymbols(java.util.List)
*/
public void addSymbols(final List<ReversePolishNotationSymbol<RS,RM>> symbols) {
this.symbolStack.addAll(symbols);
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#getStringOfSymbol()
*/
public String getStringOfSymbol() {
return this.getExpression();
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#isNegative()
*/
public boolean isNegative() {
return this.isNegative;
}
// /**
// * @see org.mklab.nfc.rpn.ReversePolishNotationOperand#isReversePolishNotationOperator()
// */
// public boolean isReversePolishNotationOperator() {
// return false;
// }
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#createSymbolStack(org.mklab.nfc.rpn.ReversePolishNotationOperand, org.mklab.nfc.rpn.ReversePolishNotationOperator)
*/
public List<ReversePolishNotationSymbol<RS,RM>> createSymbolStack(final ReversePolishNotationOperand<RS,RM> opponent, final ReversePolishNotationOperator<RS,RM> operator) {
final List<ReversePolishNotationSymbol<RS,RM>> ans = new ArrayList<>();
ans.addAll(opponent.getSymbolStack());
ans.addAll(this.getSymbolStack());
ans.add(operator);
return ans;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#setNegative(boolean)
*/
public void setNegative(final boolean isNegative) {
this.isNegative = isNegative;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#invertSign()
*/
public ConstantSystem<RS,RM,CS,CM> invertSign() {
final ConstantSystem<RS,RM,CS,CM> clone = clone();
clone.setGain(clone.getGain().unaryMinus());
clone.setNegative(!this.isNegative);
return clone;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#isZeroOperand()
*/
public boolean isZeroOperand() {
return this.gainSystem.getD().isZero();
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#add(org.mklab.nfc.rpn.ReversePolishNotationOperand)
*/
public ReversePolishNotationOperand<RS,RM> add(final ReversePolishNotationOperand<RS,RM> opponent) {
return this.add((ConstantSystem<RS,RM,CS,CM>)opponent);
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#multiply(org.mklab.nfc.rpn.ReversePolishNotationOperand)
*/
public ReversePolishNotationOperand<RS,RM> multiply(final ReversePolishNotationOperand<RS,RM> opponent) {
return this.multiply((ConstantSystem<RS,RM,CS,CM>)opponent);
}
/**
* 掛け合わされたExpressionを持つSystemが返されます。
*
* @return 掛け合わされたExpressionを持つSystem
*/
public ReversePolishNotationOperand<RS,RM> getMultipliedSystem() {
final ConstantSystem<RS,RM,CS,CM> multipliedSystem = this.clone();
final AbstractExpressionProcessor<RS,RM> processor = new ExpressionProcessor<>();
final ConstantSystem<RS,RM,CS,CM> system = (ConstantSystem<RS,RM,CS,CM>)processor.evaluate(multipliedSystem);
if (system.isSingleTerm() == false) system.getParsedOperand();
return system;
}
/**
* @see org.mklab.tool.control.system.SystemOperator#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (!super.equals(o)) {
return false;
}
if (o == null) {
return false;
}
if (o.getClass() != getClass()) {
return false;
}
ConstantSystem<RS,RM,CS,CM> castedObj = (ConstantSystem<RS,RM,CS,CM>)o;
return ((this.gainSystem == null ? castedObj.gainSystem == null : this.gainSystem.equals(castedObj.gainSystem))
&& (this.expression == null ? castedObj.expression == null : this.expression.equals(castedObj.expression)) && (this.singleTerm == castedObj.singleTerm) && (this.isNegative == castedObj.isNegative));
}
/**
* {@inheritDoc}
*/
public ReversePolishNotationOperand<RS,RM> createOperand(RM value) {
final ConstantSystem<RS,RM,CS,CM> constantSystem = new ConstantSystem<>(value);
constantSystem.setVariable(this.isVariable);
return constantSystem;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#createUnitOperand(int)
*/
public ReversePolishNotationOperand<RS,RM> createUnitOperand(final int size) {
final UnitSystem<RS,RM,CS,CM> unitSystem = new UnitSystem<>(size, this.sunit);
unitSystem.setVariable(this.isVariable);
return unitSystem;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#createNegativeUnitOperand(int)
*/
public ReversePolishNotationOperand<RS,RM> createNegativeUnitOperand(final int size) {
final NegativeUnitSystem<RS,RM,CS,CM> unitSystem = new NegativeUnitSystem<>(size, this.sunit);
unitSystem.setVariable(this.isVariable);
return unitSystem;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#setVariable(boolean)
*/
public void setVariable(boolean isVariable) {
this.isVariable = isVariable;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#isVariable()
*/
public boolean isVariable() {
return this.isVariable;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#isUnitOperand()
*/
public boolean isUnitOperand() {
return false;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#isNegativeUnitOperand()
*/
public boolean isNegativeUnitOperand() {
return false;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#getOperandValue()
*/
public RM getOperandValue() {
return getGain();
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
if (this.isNegative) {
return "-" + this.expression; //$NON-NLS-1$
}
return this.expression;
}
/**
* {@inheritDoc}
*/
public ReversePolishNotationOperand<RS,RM> toOperand() {
// TODO stub automaticaly generated
return null;
}
/**
* {@inheritDoc}
*/
public SingleOperandOperator<RS,RM> toSingleOperandOperator() {
// TODO stub automaticaly generated
return null;
}
/**
* {@inheritDoc}
*/
public DoubleOperandOperator<RS,RM> toDoubleOperandOperator() {
// TODO stub automaticaly generated
return null;
}
}