Series.java

/*
 * $Id: Series.java,v 1.12 2008/03/23 23:41:55 koga Exp $
 *
 * Copyright (C) 2004 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;


/**
 * 2つの線形システムを直列結合したシステムを求めるクラスです。
 * 
 * <p>Series connection of two systems
 * 
 * @author koga
 * @version $Revision: 1.12 $
 * @see org.mklab.tool.control.Parallel
 */
public class Series {

  /**
   * システム1
   * 
   * <pre><code> . x1 = A1 x1 + B1 u1 y1 = C1 x1 + D1 u1 </code></pre>
   * 
   * の出力をシステム2
   * 
   * <pre><code> . x2 = A2 x2 + B2 u2 y2 = C2 x2 + D2 u2 </code></pre>
   * 
   * の入力に
   * 
   * <pre><code> -1 -1 u1 ---&gt; C1(sI - A1)B1 ---&gt; y1 ---&gt; u2 ---&gt; C2(sI - A2)B2 ---&gt; y2 </code></pre>
   * 
   * のように接続したシステムを生成します。
   * 
   * @param A1 A1行列
   * @param B1 B1行列
   * @param C1 C1行列
   * @param D1 D1行列
   * @param A2 A2行列
   * @param B2 B2行列
   * @param C2 C2行列
   * @param D2 D2行列
   * @return 直列結合したシステム (series connected system)
   */
  public static List<DoubleMatrix> series(DoubleMatrix A1, DoubleMatrix B1, DoubleMatrix C1, DoubleMatrix D1, DoubleMatrix A2, DoubleMatrix B2, DoubleMatrix C2, DoubleMatrix D2) {
    String message1;
    if ((message1 = Abcdchk.abcdchk(A1, B1, C1, D1)).length() > 0) {
      throw new RuntimeException(message1);
    }

    String message2;
    if ((message2 = Abcdchk.abcdchk(A2, B2, C2, D2)).length() > 0) {
      throw new RuntimeException(message2);
    }

    int n1 = A1.getRowSize();
    int n2 = A2.getRowSize();

    DoubleMatrix A, B, C, D;

    if (n1 == 0) {
      A = A2;
      B = B2;
      C = C2;
      D = D1.multiply(D2);
    } else if (n2 == 0) {
      A = A1;
      B = B1;
      C = C1;
      D = D1.multiply(D2);
    } else {
      DoubleMatrix tmp1 = A1.appendRight(A1.createZero(n1, n2));
      DoubleMatrix tmp2 = B2.multiply(C1).appendRight(A2);
      A = tmp1.appendDown(tmp2); // A = [[ A1 ,Z(n1,n2)][B2*C1, A2 ]];
      B = B1.appendDown(B2.multiply(D1)); // [[ B1 ][B2*D1]];
      C = D2.multiply(C1).appendRight(C2); // [D2*C1 C2];
      D = D2.multiply(D1);
    }
    return new ArrayList<>(Arrays.asList(new DoubleMatrix[] {A, B, C, D}));
  }

}