Tfm2des.java
/*
* Created on 2010/09/29
* Copyright (C) 2010 Koga Laboratory. All rights reserved.
*
*/
package org.mklab.tool.control;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.mklab.nfc.matrix.DoubleMatrix;
import org.mklab.nfc.matrix.DoublePolynomialMatrix;
import org.mklab.nfc.matrix.DoubleRationalPolynomialMatrix;
import org.mklab.nfc.scalar.DoublePolynomial;
import org.mklab.nfc.scalar.DoubleRationalPolynomial;
/**
*
* 伝達関数行列(有理多項式行列)からディスクリプタ表現に変換するクラスです。 <p>Transfer function matrix to descriptor-state-space conversion</p>
*
* @author esumi
* @version $Revision$, 2010/09/29
*/
public class Tfm2des {
/**
* 多入力多出力システム(非プロパー)
*
* <pre><code>
*
* NUM(s)
* G(s) = --------
* den(s)
*
* </code></pre>
*
* の状態空間表現
*
* <pre><code>
*
* .
* Ex = Ax + Bu
* y = Cx + Du
*
* </code></pre>
*
* を求めます。 係数行列 <code>A,B,C,D</code> は、可制御正準形で返されます。
*
* @param transferFunctionMatrix 伝達関数行列
* @return Descriptor DoubleMatrix List{A,B,C,D,E} ディスクリプター表現(descriptor state space representation)
*/
public static List<DoubleMatrix> tfm2des(DoubleRationalPolynomialMatrix transferFunctionMatrix) {
final DoublePolynomialMatrix pol = transferFunctionMatrix.getQuotientElementWise();
final DoubleRationalPolynomialMatrix pro = transferFunctionMatrix.subtract(new DoubleRationalPolynomialMatrix(pol));
final List<DoubleMatrix> sp = Tfm2ss.tfm2ss(pro);
final int columnSize = transferFunctionMatrix.getColumnSize();
final int rowSize = transferFunctionMatrix.getRowSize();
final DoubleRationalPolynomialMatrix hornerPol = new DoubleRationalPolynomialMatrix(rowSize, columnSize);
final double denCoefficient = 1.0;
for (int column = 1; column <= columnSize; column++) {
for (int row = 1; row <= rowSize; row++) {
DoublePolynomial numPolynomial = new DoublePolynomial(pol.getElement(row, column).getCoefficients().flipLeftRight().divide(-1));
int numPolynomialDegree = pol.getElement(row, column).getDegree() + 1;
double[] denPolynomialCoefficient = new double[numPolynomialDegree + 1];
denPolynomialCoefficient[numPolynomialDegree] = denCoefficient;
DoublePolynomial denPolynomial = new DoublePolynomial(denPolynomialCoefficient);
hornerPol.setElement(row, column, new DoubleRationalPolynomial(numPolynomial, denPolynomial));
}
}
final List<DoubleMatrix> spol = Tfm2ss.tfm2ss(hornerPol);
final int spRowSize = sp.get(0).getRowSize();
final int spColumnSize = sp.get(0).getColumnSize();
final int spolRowSize = spol.get(0).getRowSize();
final int spolColumnSize = spol.get(0).getColumnSize();
final int inputDegree = transferFunctionMatrix.getColumnSize();
final int outputDegree = transferFunctionMatrix.getRowSize();
final DoubleMatrix A = new DoubleMatrix(spRowSize + spolRowSize, spColumnSize + spolColumnSize);
final DoubleMatrix B = new DoubleMatrix(spRowSize + spolRowSize, inputDegree);
final DoubleMatrix C = new DoubleMatrix(outputDegree, spColumnSize + spolColumnSize);
final DoubleMatrix D = new DoubleMatrix(outputDegree, inputDegree);
final DoubleMatrix E = new DoubleMatrix(spRowSize + spolRowSize, spColumnSize + spolColumnSize);
final DoubleMatrix leftLowerMatrix = new DoubleMatrix(spolRowSize, spColumnSize);
final DoubleMatrix upperRightMatrix = new DoubleMatrix(spRowSize, spolColumnSize);
A.setSubMatrix(1, spRowSize, 1, spColumnSize, sp.get(0));
A.setSubMatrix(spRowSize + 1, spRowSize + spolRowSize, 1, spColumnSize, leftLowerMatrix);
A.setSubMatrix(1, spRowSize, spColumnSize + 1, spColumnSize + spolColumnSize, upperRightMatrix);
A.setSubMatrix(spRowSize + 1, spRowSize + spolRowSize, spColumnSize + 1, spColumnSize + spolColumnSize, DoubleMatrix.unit(spolRowSize, spolColumnSize));
B.setSubMatrix(1, spRowSize, 1, inputDegree, sp.get(1));
B.setSubMatrix(spRowSize + 1, spRowSize + spolRowSize, 1, inputDegree, spol.get(1));
C.setSubMatrix(1, outputDegree, 1, spColumnSize, sp.get(2));
C.setSubMatrix(1, outputDegree, spColumnSize + 1, spColumnSize + spolColumnSize, spol.get(2));
E.setSubMatrix(1, spRowSize, 1, spColumnSize, DoubleMatrix.unit(spRowSize, spColumnSize));
E.setSubMatrix(spRowSize + 1, spRowSize + spolRowSize, 1, spColumnSize, leftLowerMatrix);
E.setSubMatrix(1, spRowSize, spColumnSize + 1, spColumnSize + spolColumnSize, upperRightMatrix);
E.setSubMatrix(spRowSize + 1, spRowSize + spolRowSize, spColumnSize + 1, spColumnSize + spolColumnSize, spol.get(0));
return new ArrayList<>(Arrays.asList(new DoubleMatrix[] {A, B, C, D, E}));
}
}