LinearSystemFactory.java

/*
 * Created on 2009/07/01
 * Copyright (C) 2009 Koga Laboratory. All rights reserved.
 *
 */
package org.mklab.tool.control;

import org.mklab.nfc.matrix.AnyRealRationalPolynomialMatrix;
import org.mklab.nfc.matrix.ComplexNumericalMatrix;
import org.mklab.nfc.matrix.IntMatrix;
import org.mklab.nfc.matrix.RealNumericalMatrix;
import org.mklab.nfc.scalar.AnyRealRationalPolynomial;
import org.mklab.nfc.scalar.ComplexNumericalScalar;
import org.mklab.nfc.scalar.RealNumericalScalar;


/**
 * 線形システムのインスタンスを生成するFactoryクラスです.
 * 
 * @author Anan
 * @version $Revision$, 2009/08/30
 */
public class LinearSystemFactory {

  /**
   * 状態空間表現の係数行列から線形システムを生成します。
   * 
   * @param a システム行列
   * @param b 入力行列
   * @param c 出力行列
   * @param d ゲイン行列
   * @return ProperLinearSystemのインスタンス
   * @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 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>> ProperLinearSystem<RS, RM, CS, CM> createLinearSystem(
      final RM a, final RM b, final RM c, final RM d) {
    return new ProperLinearSystem<>(a, b, c, d);
  }

  /**
   * 1入力1出力システムの伝達関数から線形システムを生成します。
   * 
   * @param transferFunction 1入力1出力システムの伝達関数(有理多項式)
   * @return ProperLinearSystemのインスタンス
   * @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 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>> LinearSystem<RS, RM, CS, CM> createLinearSystem(
      final AnyRealRationalPolynomial<RS, RM, CS, CM> transferFunction) {
    final boolean proper = transferFunction.getNumeratorDegree() <= transferFunction.getDenominatorDegree();
    if (proper) {
      return new ProperLinearSystem<>(transferFunction);
    }
    return new ImproperLinearSystem<>(transferFunction);
  }

  /**
   * 伝達関数行列から線形システムを生成します。
   * 
   * @param transferFunctionMatrix 伝達関数行列(有理多項式行列)
   * @return ProperLinearSystemのインスタンス
   * @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 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>> LinearSystem<RS, RM, CS, CM> createLinearSystem(
      final AnyRealRationalPolynomialMatrix<RS, RM, CS, CM> transferFunctionMatrix) {
    boolean proper = true;
    for (int row = 1; row <= transferFunctionMatrix.getRowSize(); row++) {
      for (int column = 1; column <= transferFunctionMatrix.getColumnSize(); column++) {
        final AnyRealRationalPolynomial<RS, RM, CS, CM> function = transferFunctionMatrix.getElement(row, column);
        if (function.getNumeratorDegree() > function.getDenominatorDegree()) {
          proper = false;
          break;
        }
      }
    }

    if (proper) {
      return new ProperLinearSystem<>(transferFunctionMatrix);
    }
    return new ImproperLinearSystem<>(transferFunctionMatrix);
  }

  /**
   * 係数行列から線形システムを生成します。
   * 
   * @param a 状態行列
   * @param b ゲイン行列
   * @param c 出力行列
   * @param d ゲイン行列
   * @param e ディスクリプター行列
   * @return LinearSystemのインスタンス
   * @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 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>> LinearSystem<RS, RM, CS, CM> createLinearSystem(
      final RM a, final RM b, final RM c, final RM d, final RM e) {
    if (e.isUnit() || e.isEmpty() || e.isFullRank()) {
      return new ProperLinearSystem<>(a, b, c, d, e);
    }
    return new ImproperLinearSystem<>(a, b, c, d, e);
  }

  /**
   * 係数行列から線形システムを生成します。
   * 
   * @param a 状態行列
   * @param b ゲイン行列
   * @param c 出力行列
   * @param d ゲイン行列
   * @param e ディスクリプター行列
   * @param index 指数
   * @return LinearSystemのインスタンス
   * @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 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>> LinearSystem<RS, RM, CS, CM> createLinearSystem(
      final RM a, final RM b, final RM c, final RM d, final RM e, final IntMatrix index) {
    return new ImproperLinearSystem<>(a, b, c, d, e, index);
  }

  /**
   * 係数行列からisDescriptorFormに応じて,ディスクリプタ形式、または、状態空間表現で線形システムを生成します.
   * 
   * @param a 状態行列
   * @param b ゲイン行列
   * @param c 出力行列
   * @param d ゲイン行列
   * @param e ディスクリプタ行列
   * @param isDescriptorForm ディスクリプタ形式で求めるならばtrue
   * @return isDescriptrFormがtrueならばDescriptorFormのImproperSystemのインスタンス,falseならばLinearSystemのインスタンス
   * @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 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>> LinearSystem<RS, RM, CS, CM> createLinearSystem(
      final RM a, final RM b, final RM c, final RM d, final RM e, final boolean isDescriptorForm) {
    if (isDescriptorForm) {
      return new ImproperLinearSystem<>(a, b, c, d, e);
    }
    return createLinearSystem(a, b, c, d, e);
  }

  /**
   * 係数行列からisDescriptorFormに応じて,ディスクリプタ形式、または、状態空間表現で線形システムを生成します.
   * 
   * @param a 状態行列
   * @param b ゲイン行列
   * @param c 出力行列
   * @param d ゲイン行列
   * @param e ディスクリプタ行列
   * @param index 指数
   * @param isDescriptorForm ディスクリプタ形式で求めるならばtrue
   * @return isDescriptrFormがtrueならばDescriptorFormのImproperSystemのインスタンス,falseならばLinearSystemのインスタンス
   * @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 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>> LinearSystem<RS, RM, CS, CM> createLinearSystem(
      final RM a, final RM b, final RM c, final RM d, final RM e, final IntMatrix index, final boolean isDescriptorForm) {
    if (isDescriptorForm) {
      return new ImproperLinearSystem<>(a, b, c, d, e, index);
    }
    return createLinearSystem(a, b, c, d, e, index);
  }

  /**
   * 定数行列から線形システム(定数システム)を生成します。
   * 
   * @param gain 定数行列
   * @return 定数システム
   * @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 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>> ProperLinearSystem<RS, RM, CS, CM> createConstant(
      final RM gain) {
    final RM a = gain.createZero(0, 0);
    final RM b = gain.createZero(0, gain.getColumnSize());
    final RM c = gain.createZero(gain.getRowSize(), 0);
    final RM e = gain.createUnit();
    return (ProperLinearSystem<RS, RM, CS, CM>)createLinearSystem(a, b, c, gain, e);
  }
}