DoubleConstantSystem.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.DoubleMatrix;
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.DoubleNumber;
import org.mklab.nfc.scalar.DoubleNumberUtil;
import org.mklab.tool.control.DoubleLinearSystem;
import org.mklab.tool.control.DoubleLinearSystemFactory;
import org.mklab.tool.control.system.DoubleLinearSystemOperator;
import org.mklab.tool.control.system.SymbolicOperator;
import org.mklab.tool.control.system.continuous.DoubleBaseContinuousStaticSystem;
import org.mklab.tool.control.system.continuous.DoubleContinuousLinearDynamicSystem;
/**
* 定数システムを表わすクラスです。
*
* @author Koga Laboratory
* @version $Revision: 1.41 $, 2004/11/12
*/
public class DoubleConstantSystem extends DoubleBaseContinuousStaticSystem implements DoubleLinearSystemOperator, SymbolicOperator, ReversePolishNotationOperand<DoubleNumber,DoubleMatrix> {
/** システム */
private DoubleLinearSystem gainSystem;
/** 数式 */
private String expression = ""; //$NON-NLS-1$
/** 1個の項として扱えるシステムならばtrue */
private boolean singleTerm = true;
/** シンボルのスタック */
private List<ReversePolishNotationSymbol<DoubleNumber,DoubleMatrix>> 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 出力数
*/
public DoubleConstantSystem(final int inputSize, final int outputSize) {
super(inputSize, outputSize);
setHasDirectFeedthrough(true);
setLinear(true);
this.tag = "" + hashCode(); //$NON-NLS-1$
this.symbolStack.add(this);
}
/**
* 新しく生成された<code>ConstantSystem</code>オブジェクトを初期化します。
*
* @param gain 定数ゲイン行列
*/
public DoubleConstantSystem(final DoubleMatrix gain) {
this(gain.getColumnSize(), gain.getRowSize());
this.gainSystem = DoubleLinearSystemFactory.createConstant(gain);
final int inputSize = gain.getColumnSize();
final int outputSize = gain.getRowSize();
this.expression = "DoubleConstantSystem(" + inputSize + " inputs, " + outputSize + " outputs)"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
/**
* 定数ゲイン行列を設定します。
*
* @param gain 定数ゲイン行列
*/
public void setGain(final DoubleMatrix gain) {
this.gainSystem = DoubleLinearSystemFactory.createConstant(gain);
}
/**
* {@inheritDoc}
*/
@Override
public DoubleMatrix outputEquation( final double t, final DoubleMatrix u) {
return this.gainSystem.getD().multiply(u);
}
/**
* 単位システムであるか判定します。
*
* @return 単位システムならtrue、そうでなければfalse
*/
public boolean isUnit() {
final DoubleMatrix K = this.gainSystem.getD();
return K.getRowSize() == K.getColumnSize() && K.isUnit();
}
/**
* 負の単位システムであるか判定します。
*
* @return 負の単位システムならtrue、そうでなければfalse
*/
public boolean isNegativeUnit() {
final DoubleMatrix K = this.gainSystem.getD();
return K.getRowSize() == K.getColumnSize() && K.unaryMinus().isUnit();
}
/**
* 二つのシステムの和システムを返します。
*
* @param opponent 足すシステム
* @return 結合したシステム
*/
public DoubleConstantSystem add(final DoubleConstantSystem opponent) {
final DoubleMatrix gain = this.gainSystem.getD().add(opponent.gainSystem.getD());
final DoubleConstantSystem constantSystem = new DoubleConstantSystem(gain);
constantSystem.setVariable(this.isVariable || opponent.isVariable);
if (requiringABCD == false) {
return constantSystem;
}
constantSystem.setSymbolStack(this.createSymbolStack(opponent, new AddOperator<DoubleNumber,DoubleMatrix>()));
return constantSystem;
}
/**
* 二つのシステムの差システムを返します。
*
* @param opponent 引くシステム
* @return 結合したシステム
*/
public DoubleConstantSystem subtract(final DoubleConstantSystem opponent) {
final DoubleConstantSystem constantSystem = new DoubleConstantSystem(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 DoubleConstantSystem first, final DoubleConstantSystem 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 DoubleConstantSystem multiply(final DoubleConstantSystem opponent) {
if (opponent instanceof DoubleUnitSystem) {
return this;
}
final DoubleMatrix gain = this.gainSystem.getD().multiply(opponent.gainSystem.getD());
final DoubleConstantSystem constantSystem = new DoubleConstantSystem(gain);
constantSystem.setVariable(this.isVariable || opponent.isVariable);
if (requiringABCD == false) {
return constantSystem;
}
constantSystem.setSymbolStack(this.createSymbolStack(opponent, new MultiplyOperator<DoubleNumber,DoubleMatrix>()));
return constantSystem;
}
/**
* (ネガティブ)フィードバック結合したシステムを返します。
*
* @param opponent フィードバック成分
* @return 結合したシステム
*/
public DoubleConstantSystem feedback(final DoubleConstantSystem opponent) {
return feedback(opponent, true);
}
/**
* フィードバック結合したシステムを返します。
*
* @param opponent フィードバック要素
* @param negativeFeedback ネガティブフィードバックならばtrue、そうでなければfalse
* @return 結合したシステム
*/
public DoubleConstantSystem feedback(final DoubleConstantSystem opponent, final boolean negativeFeedback) {
final DoubleMatrix gain1 = this.gainSystem.getD();
final DoubleMatrix gain2 = opponent.gainSystem.getD();
if (negativeFeedback) {
DoubleConstantSystem constantSystem = new DoubleConstantSystem(DoubleMatrix.unit(gain1.getRowSize()).add(gain1.multiply(gain2)).leftDivide(gain1));
constantSystem.setVariable(this.isVariable || opponent.isVariable);
return constantSystem;
}
DoubleConstantSystem constantSystem = new DoubleConstantSystem(DoubleMatrix.unit(gain1.getRowSize()).subtract(gain1.multiply(gain2)).leftDivide(gain1));
constantSystem.setVariable(this.isVariable || opponent.isVariable);
return constantSystem;
}
/**
* 定数ゲイン行列を返します。
*
* @return 定数ゲイン行列
*/
public DoubleMatrix getGain() {
return this.gainSystem.getD();
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#getLinearSystem()
*/
@Override
public DoubleLinearSystem getLinearSystem() {
return this.gainSystem;
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#setLinearSystem(org.mklab.tool.control.LinearSystem)
*/
public void setLinearSystem(final DoubleLinearSystem 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 DoubleMatrix getA() {
return this.gainSystem.getA();
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#getB()
*/
public DoubleMatrix getB() {
return this.gainSystem.getB();
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#getC()
*/
public DoubleMatrix getC() {
return this.gainSystem.getC();
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#getD()
*/
public DoubleMatrix getD() {
return this.gainSystem.getD();
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#getE()
*/
public DoubleMatrix getE() {
return this.gainSystem.getE();
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#add(org.mklab.tool.control.system.LinearSystemOperator)
*/
public DoubleLinearSystemOperator add(final DoubleLinearSystemOperator opponent) {
return add(opponent, true);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#add(org.mklab.tool.control.system.LinearSystemOperator, boolean)
*/
public DoubleLinearSystemOperator add(final DoubleLinearSystemOperator opponent, final boolean simplify) {
return new DoubleContinuousLinearDynamicSystem(this.gainSystem.add(opponent.getLinearSystem(), simplify));
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#subtract(org.mklab.tool.control.system.LinearSystemOperator)
*/
public DoubleLinearSystemOperator subtract(final DoubleLinearSystemOperator opponent) {
return subtract(opponent, true);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#subtract(org.mklab.tool.control.system.LinearSystemOperator, boolean)
*/
public DoubleLinearSystemOperator subtract(final DoubleLinearSystemOperator opponent, final boolean simplify) {
return new DoubleContinuousLinearDynamicSystem(this.gainSystem.subtract(opponent.getLinearSystem(), simplify));
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#multiply(org.mklab.tool.control.system.LinearSystemOperator)
*/
public DoubleLinearSystemOperator multiply(final DoubleLinearSystemOperator system) {
return multiply(system, true);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#multiply(org.mklab.tool.control.system.LinearSystemOperator, boolean)
*/
public DoubleLinearSystemOperator multiply(final DoubleLinearSystemOperator opponent, final boolean simplify) {
return new DoubleContinuousLinearDynamicSystem(this.gainSystem.multiply(opponent.getLinearSystem(), simplify));
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#feedback(org.mklab.tool.control.system.LinearSystemOperator)
*/
public DoubleLinearSystemOperator feedback(final DoubleLinearSystemOperator system) {
return feedback(system, true, true);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#feedback(org.mklab.tool.control.system.LinearSystemOperator, boolean)
*/
public DoubleLinearSystemOperator feedback(final DoubleLinearSystemOperator 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 DoubleLinearSystemOperator feedback(final DoubleLinearSystemOperator opponent, final boolean negativeFeedback, final boolean simplify) {
return new DoubleContinuousLinearDynamicSystem(this.gainSystem.feedback(opponent.getLinearSystem(), negativeFeedback, simplify));
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#unaryMinus()
*/
public DoubleConstantSystem unaryMinus() {
// final ConstantSystem constantSystem = new ConstantSystem(this.gainSystem.getD().unaryMinus());
// constantSystem.setVariable(this.isVariable);
//
// if (requiringABCD == false) {
// return constantSystem;
// }
// constantSystem.setUnaryMinusExpression(this);
// return constantSystem;
return this.multiply(new DoubleNegativeUnitSystem(this.gainSystem.getD().getColumnSize()));
}
/**
* 符号を反転した数式を設定します。
*
* @param system 対象となるシステム
*/
protected void setUnaryMinusExpression(final DoubleConstantSystem 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 DoubleConstantSystem unityFeedback() {
return unityFeedback(true, true);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#unityFeedback(boolean)
*/
public DoubleConstantSystem unityFeedback(final boolean negativeFeedback) {
return unityFeedback(negativeFeedback, true);
}
/**
* @see org.mklab.tool.control.system.LinearSystemOperator#unityFeedback(boolean, boolean)
*/
public DoubleConstantSystem unityFeedback(final boolean negativeFeedback, final boolean simplify) {
final DoubleMatrix K = this.gainSystem.getD();
if (negativeFeedback) {
DoubleConstantSystem constantSystem = new DoubleConstantSystem(DoubleMatrix.unit(K).add(K).leftDivide(K));
constantSystem.setVariable(this.isVariable);
return constantSystem;
}
DoubleConstantSystem constantSystem = new DoubleConstantSystem(DoubleMatrix.unit(K).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 DoubleMatrix K = getGain();
if (K.getRowSize() != K.getColumnSize()) {
return false;
}
if (negativeFeedback) {
return DoubleMatrix.unit(K).add(K).isFullRank();
}
return DoubleMatrix.unit(K).subtract(K).isFullRank();
}
/**
* 単一フィードバック系の感度関数「(I + K)~」(負フィードバック)、「(I - K)~」(正フィードバック)を返します。
*
* @param negativeFeedback 負フィードバックならばtrue、正フィードバックならばfalse
* @return 単一フィードバック系の感度関数「(I + K)~」(負フィードバック)、「(I - K)~」(正フィードバック)
*/
public DoubleConstantSystem getSensitivityOfUnityFeedback(final boolean negativeFeedback) {
final DoubleMatrix K = getGain();
final DoubleMatrix gain = negativeFeedback ? DoubleMatrix.unit(K).add(K).inverse() : DoubleMatrix.unit(K).subtract(K).inverse();
final DoubleConstantSystem constantSystem = new DoubleConstantSystem(gain);
constantSystem.setVariable(this.isVariable);
if (requiringABCD == false) {
return constantSystem;
}
if (isZero() || this.gainSystem.getD().isZero()) {
return new DoubleUnitSystem(getInputSize());
}
final DoubleConstantSystem system = negativeFeedback ? new DoubleUnitSystem(constantSystem.getInputSize()).add(this) : new DoubleUnitSystem(constantSystem.getInputSize()).add(this.multiply(new DoubleNegativeUnitSystem(
this.getInputSize())));
system.setVariable(this.isVariable);
system.setSingleTerm(false);
return (system).inverse();
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#inverse()
*/
public DoubleConstantSystem inverse() {
final DoubleMatrix gain = getGain();
gain.singularValue();
final boolean stopIfSingular = true;
final DoubleMatrix inversGain = gain.inverse(gain.frobNorm().doubleValue() * DoubleNumberUtil.EPS, stopIfSingular);
final DoubleConstantSystem constantSystem = (DoubleConstantSystem)this.createOperand(inversGain);
constantSystem.setVariable(this.isVariable);
constantSystem.getSymbolStack().remove(0);
constantSystem.addSymbol(this);
constantSystem.addSymbol(new InverseOperator<DoubleNumber,DoubleMatrix>());
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) {
DoubleConstantSystem.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 DoubleConstantSystem clone() {
final DoubleConstantSystem inst = (DoubleConstantSystem)super.clone();
if (this.gainSystem != null) {
inst.gainSystem = (DoubleLinearSystem)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<DoubleNumber,DoubleMatrix> getParsedOperand() {
String composedExpression = ""; //$NON-NLS-1$
for (final ReversePolishNotationSymbol<DoubleNumber,DoubleMatrix> symbol : this.getSymbolStack()) {
final String singleExpression = ((ReversePolishNotationOperand<DoubleNumber,DoubleMatrix>)symbol).getExpression();
if (composedExpression.equals("")) { //$NON-NLS-1$
//if (this.isNegative()) {
if (((ReversePolishNotationOperand<DoubleNumber,DoubleMatrix>)symbol).isNegative()) {
composedExpression = ((ReversePolishNotationOperand<DoubleNumber,DoubleMatrix>)symbol).getSignedExpression();
} else {
composedExpression = singleExpression;
}
continue;
}
if (((ReversePolishNotationOperand<DoubleNumber,DoubleMatrix>)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<DoubleNumber,DoubleMatrix>> reversePolishNotationSymbolStack) {
this.symbolStack = reversePolishNotationSymbolStack;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#getSymbolStack()
*/
public List<ReversePolishNotationSymbol<DoubleNumber,DoubleMatrix>> getSymbolStack() {
return this.symbolStack;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#addSymbol(org.mklab.nfc.rpn.ReversePolishNotationSymbol)
*/
public void addSymbol(final ReversePolishNotationSymbol<DoubleNumber,DoubleMatrix> symbol) {
this.symbolStack.add(symbol);
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#addSymbols(java.util.List)
*/
public void addSymbols(final List<ReversePolishNotationSymbol<DoubleNumber,DoubleMatrix>> 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<DoubleNumber,DoubleMatrix>> createSymbolStack(final ReversePolishNotationOperand<DoubleNumber,DoubleMatrix> opponent, final ReversePolishNotationOperator<DoubleNumber,DoubleMatrix> operator) {
final List<ReversePolishNotationSymbol<DoubleNumber,DoubleMatrix>> 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 DoubleConstantSystem invertSign() {
final DoubleConstantSystem 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<DoubleNumber,DoubleMatrix> add(final ReversePolishNotationOperand<DoubleNumber,DoubleMatrix> opponent) {
return this.add((DoubleConstantSystem)opponent);
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#multiply(org.mklab.nfc.rpn.ReversePolishNotationOperand)
*/
public ReversePolishNotationOperand<DoubleNumber,DoubleMatrix> multiply(final ReversePolishNotationOperand<DoubleNumber,DoubleMatrix> opponent) {
return this.multiply((DoubleConstantSystem)opponent);
}
/**
* 掛け合わされたExpressionを持つSystemが返されます。
*
* @return 掛け合わされたExpressionを持つSystem
*/
public ReversePolishNotationOperand<DoubleNumber,DoubleMatrix> getMultipliedSystem() {
final DoubleConstantSystem multipliedSystem = this.clone();
final AbstractExpressionProcessor<DoubleNumber,DoubleMatrix> processor = new ExpressionProcessor<>();
final DoubleConstantSystem system = (DoubleConstantSystem)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;
}
DoubleConstantSystem castedObj = (DoubleConstantSystem)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<DoubleNumber,DoubleMatrix> createOperand(DoubleMatrix value) {
final DoubleConstantSystem constantSystem = new DoubleConstantSystem(value);
constantSystem.setVariable(this.isVariable);
return constantSystem;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#createUnitOperand(int)
*/
public ReversePolishNotationOperand<DoubleNumber,DoubleMatrix> createUnitOperand(final int size) {
final DoubleUnitSystem unitSystem = new DoubleUnitSystem(size);
unitSystem.setVariable(this.isVariable);
return unitSystem;
}
/**
* @see org.mklab.nfc.rpn.ReversePolishNotationOperand#createNegativeUnitOperand(int)
*/
public ReversePolishNotationOperand<DoubleNumber,DoubleMatrix> createNegativeUnitOperand(final int size) {
final DoubleNegativeUnitSystem unitSystem = new DoubleNegativeUnitSystem(size);
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 DoubleMatrix getOperandValue() {
return getGain();
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
if (this.isNegative) {
return "-" + this.expression; //$NON-NLS-1$
}
return this.expression;
}
/**
* {@inheritDoc}
*/
public ReversePolishNotationOperand<DoubleNumber, DoubleMatrix> toOperand() {
// TODO stub automaticaly generated
return null;
}
/**
* {@inheritDoc}
*/
public SingleOperandOperator<DoubleNumber, DoubleMatrix> toSingleOperandOperator() {
// TODO stub automaticaly generated
return null;
}
/**
* {@inheritDoc}
*/
public DoubleOperandOperator<DoubleNumber, DoubleMatrix> toDoubleOperandOperator() {
// TODO stub automaticaly generated
return null;
}
}