Ss2tf.java

  1. /*
  2.  * $Id: Ss2tf.java,v 1.25 2008/03/24 14:57:16 koga Exp $
  3.  *
  4.  * Copyright (C) 2004 Koga Laboratory. All rights reserved.
  5.  */
  6. package org.mklab.tool.control;

  7. import java.util.ArrayList;
  8. import java.util.Arrays;
  9. import java.util.List;

  10. import org.mklab.nfc.matrix.ComplexNumericalMatrix;
  11. import org.mklab.nfc.matrix.DoubleMatrix;
  12. import org.mklab.nfc.matrix.RealNumericalMatrix;
  13. import org.mklab.nfc.scalar.ComplexNumericalScalar;
  14. import org.mklab.nfc.scalar.RealNumericalScalar;
  15. import org.mklab.tool.matrix.Makepoly;


  16. /**
  17.  * 状態空間表現から伝達関数(係数からなる行列)に変換するクラスです。
  18.  *
  19.  * <p>State-space to transfer function conversion
  20.  *
  21.  * @author koga
  22.  * @version $Revision: 1.25 $
  23.  * @see org.mklab.tool.control.Ss2tfm
  24.  * @see org.mklab.tool.control.Ss2tfn
  25.  * @see org.mklab.tool.control.Ss2zp
  26.  * @see org.mklab.tool.control.Tf2ss
  27.  */
  28. public class Ss2tf {

  29.   /**
  30.    * @param A システム行列
  31.    * @param B 入力行列
  32.    * @param C 出力行列
  33.    * @param D ゲイン行列
  34.    * @return 伝達関数 (transfer function)
  35.    */
  36.   public static List<DoubleMatrix> ss2tf(DoubleMatrix A, DoubleMatrix B, DoubleMatrix C, DoubleMatrix D) {
  37.     int inputNumber = 1;
  38.     return ss2tf(A, B, C, D, inputNumber);
  39.   }

  40.   /**
  41.    * 状態空間表現が
  42.    *
  43.    * <pre><code> . x = Ax + Bu y = Cx + Du </code></pre>
  44.    *
  45.    * であるシステムの<code>i</code>番目の入力から出力までの伝達関数
  46.    *
  47.    * <pre><code>
  48.    *
  49.    * NUM(s) -1 G(s) = -------- = C(sI-A) B + D den(s) </code></pre>
  50.    *
  51.    * の分子行列多項式の係数行列<code>NUM</code>と分母多項式の係数 <code>den</code>を求めます。
  52.    *
  53.    * <p><code>NUM</code>の大きさは、<code>Rows(C)×Rows(A)</code>、 <code>den</code>の大きさは、<code>1-by-Rows(A)</code>です。
  54.    *
  55.    * @param A システム行列
  56.    * @param B 入力行列
  57.    * @param C 出力行列
  58.    * @param D ゲイン行列
  59.    * @param inputNumber 入力番号
  60.    * @return 伝達関数 (transfer function)
  61.    */
  62.   public static List<DoubleMatrix> ss2tf(DoubleMatrix A, DoubleMatrix B, DoubleMatrix C, DoubleMatrix D, int inputNumber) {
  63.     String message;
  64.     if ((message = Abcdchk.abcdchk(A, B, C, D)).length() > 0) {
  65.       throw new RuntimeException(message);
  66.     }

  67.     int outputSize = C.getRowSize();

  68.     DoubleMatrix numerators;
  69.     if (A.isReal() && B.isReal() && C.isReal() && D.isReal()) {
  70.       numerators = A.createZero(outputSize, A.getRowSize() + 1);
  71.     } else {
  72.       DoubleMatrix zero = A.createZero(outputSize, A.getRowSize() + 1);
  73.       numerators = zero;
  74.     }

  75.     DoubleMatrix Bi = B.getColumnVector(inputNumber);
  76.     DoubleMatrix Di = D.getColumnVector(inputNumber);
  77.     DoubleMatrix denominator = Makepoly.makepoly(A).getCoefficients();

  78.     for (int j = 1; j <= outputSize; j++) {
  79.       if (C.length() == 0) {
  80.         numerators.setElement(j, 1, Di.getElement(j));
  81.       } else {
  82.         DoubleMatrix tmp1 = A.subtract(Bi.multiply(C.getRowVector(j)));
  83.         DoubleMatrix tmp2 = Makepoly.makepoly(tmp1).getCoefficients();
  84.         DoubleMatrix tmp3 = tmp2.add(denominator.multiply(Di.getElement(j).subtract(1)));
  85.         numerators.setRowVector(j, tmp3);
  86.       }
  87.     }

  88.     return new ArrayList<>(Arrays.asList(new DoubleMatrix[] {numerators, denominator}));
  89.     //return new MatxList(new Object[] {numerators, denominator});
  90.   }

  91.   /**
  92.    * @param A システム行列
  93.    * @param B 入力行列
  94.    * @param C 出力行列
  95.    * @param D ゲイン行列
  96.    * @return 伝達関数 (transfer function)
  97.    * @param <RS> type of real scalar
  98.    * @param <RM> type of real matrix
  99.    * @param <CS> type of complex scalar
  100.    * @param <CM> type of complex matrix
  101.    */
  102.   public static <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>> List<RM> ss2tf(
  103.       RM A, RM B, RM C, RM D) {
  104.     int inputNumber = 1;
  105.     return ss2tf(A, B, C, D, inputNumber);
  106.   }

  107.   /**
  108.    * 状態空間表現が
  109.    *
  110.    * <pre><code> . x = Ax + Bu y = Cx + Du </code></pre>
  111.    *
  112.    * であるシステムの<code>i</code>番目の入力から出力までの伝達関数
  113.    *
  114.    * <pre><code>
  115.    *
  116.    * NUM(s) -1 G(s) = -------- = C(sI-A) B + D den(s) </code></pre>
  117.    *
  118.    * の分子行列多項式の係数行列<code>NUM</code>と分母多項式の係数 <code>den</code>を求めます。
  119.    *
  120.    * <p><code>NUM</code>の大きさは、<code>Rows(C)×Rows(A)</code>、 <code>den</code>の大きさは、<code>1-by-Rows(A)</code>です。
  121.    *
  122.    * @param A システム行列
  123.    * @param B 入力行列
  124.    * @param C 出力行列
  125.    * @param D ゲイン行列
  126.    * @param inputNumber 入力番号
  127.    * @return 伝達関数 (transfer function)
  128.    * @param <RS> type of real scalar
  129.    * @param <RM> type of real matrix
  130.    * @param <CS> type of complex scalar
  131.    * @param <CM> type of complex matrix
  132.    */
  133.   public static <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>> List<RM> ss2tf(
  134.       RM A, RM B, RM C, RM D, int inputNumber) {
  135.     String message;
  136.     if ((message = Abcdchk.abcdchk(A, B, C, D)).length() > 0) {
  137.       throw new RuntimeException(message);
  138.     }

  139.     int outputSize = C.getRowSize();

  140.     RM numerators;
  141.     if (A.isReal() && B.isReal() && C.isReal() && D.isReal()) {
  142.       numerators = A.createZero(outputSize, A.getRowSize() + 1);
  143.     } else {
  144.       RM zero = A.createZero(outputSize, A.getRowSize() + 1);
  145.       numerators = zero;
  146.     }

  147.     RM Bi = B.getColumnVector(inputNumber);
  148.     RM Di = D.getColumnVector(inputNumber);
  149.     RM denominator = Makepoly.makepoly(A).getCoefficients();

  150.     for (int j = 1; j <= outputSize; j++) {
  151.       if (C.length() == 0) {
  152.         numerators.setElement(j, 1, Di.getElement(j));
  153.       } else {
  154.         RM tmp1 = A.subtract(Bi.multiply(C.getRowVector(j)));
  155.         RM tmp2 = Makepoly.makepoly(tmp1).getCoefficients();
  156.         RM tmp3 = tmp2.add(denominator.multiply(Di.getElement(j).subtract(1)));
  157.         numerators.setRowVector(j, tmp3);
  158.       }
  159.     }

  160.     List<RM> nd = new ArrayList<>();
  161.     nd.add(numerators);
  162.     nd.add(denominator);
  163.     return nd;
  164.   }

  165. }