BlockContinuousSystem.java

/**
 * $Id$
 *
 * Copyright (C) 2004-2005 Koga Laboratory. All rights reserved.
 */

package org.mklab.tool.control.system.continuous;

import java.util.ArrayList;
import java.util.List;

import org.mklab.nfc.matrix.ComplexNumericalMatrix;
import org.mklab.nfc.matrix.RealNumericalMatrix;
import org.mklab.nfc.ode.SolverStopException;
import org.mklab.nfc.scalar.ComplexNumericalScalar;
import org.mklab.nfc.scalar.RealNumericalScalar;
import org.mklab.tool.control.LinearSystem;
import org.mklab.tool.control.system.BlockSystem;
import org.mklab.tool.control.system.DynamicSystem;
import org.mklab.tool.control.system.LinearSystemOperator;
import org.mklab.tool.control.system.StaticSystem;
import org.mklab.tool.control.system.SystemOperator;


/**
 * 連続な方程式で表現されるブロック連続時間システムを表わすクラスです。
 * 
 * @author koga
 * @version $Revision$
 * @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 abstract class BlockContinuousSystem<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>> extends BlockSystem<RS,RM,CS,CM> {

  /** ノードの値を求める時刻 */
  private RS time;

  /** 連続時間動的システムのリスト */
  protected List<ContinuousDynamicSystem<RS,RM,CS,CM>> continuousDynamicSystems = new ArrayList<>();

  /**
   * 新しく生成された<code>BlockContinuousSystem</code>オブジェクトを初期化します。
   * 
   * @param elements 隣接行列
   * @param inputNodes 入力ノードの番号のリスト(番号は1から始まります)
   * @param outputNodes 出力ノードの番号のリスト(番号は1から始まります)
   * @param sunit unit of scalar
   */
  public BlockContinuousSystem(final SystemOperator<RS,RM,CS,CM>[][] elements, final List<Integer> inputNodes, final List<Integer> outputNodes, RS sunit) {
    super(elements, inputNodes, outputNodes, sunit);
    setupContinuousDynamicSystems();
    separateDirectFeedthroughAndNonDirectFeedthrough();
  }

  /**
   * 連続時間動的システムのリストを設定します。
   */
  private void setupContinuousDynamicSystems() {
    this.continuousDynamicSystems.clear();

    final int size = getNodeSize();

    for (int row = 0; row < size; row++) {
      for (int column = 0; column < size; column++) {
        final SystemOperator<RS,RM,CS,CM> system = getSystemOperator(row, column);
        if (system instanceof ContinuousDynamicSystem) {
          this.continuousDynamicSystems.add((ContinuousDynamicSystem<RS,RM,CS,CM>)system);
        }
      }
    }
  }

  /**
   * ノードの値を計算します。
   * 
   * @param t 時刻
   * @exception SolverStopException ソルバーが停止された場合
   */
  protected void calcNodeValue(final RS t) throws SolverStopException {
    this.time = t;
    calcNodeValue();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected RM calcOutputOfDirectFeedthroughSystem(final SystemOperator<RS,RM,CS,CM> system, final RM u) throws SolverStopException {
    if (system instanceof DynamicSystem) {
      final DynamicSystem<RS,RM,CS,CM> dSystem = (DynamicSystem<RS,RM,CS,CM>)system;
      return dSystem.outputEquation(this.time, dSystem.getState(), u);
    }

    return ((StaticSystem<RS,RM,CS,CM>)system).outputEquation(this.time, u);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected RM calcOutputOfNonDirectFeedthroughSystem(final SystemOperator<RS,RM,CS,CM> system) throws SolverStopException {
    if (system == null) throw new NullPointerException();

    if (system instanceof DynamicSystem) {
      final DynamicSystem<RS,RM,CS,CM> dSystem = (DynamicSystem<RS,RM,CS,CM>)system;
      return dSystem.outputEquation(this.time, dSystem.getState());
    }

    return ((StaticSystem<RS,RM,CS,CM>)system).outputEquation(this.time);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected SystemOperator<RS,RM,CS,CM> createStrictlyProperLinearDynamicSystem(final SystemOperator<RS,RM,CS,CM> system) {
    final LinearSystem<RS,RM,CS,CM> linearSystem = ((LinearSystemOperator<RS,RM,CS,CM>)system).getLinearSystem();
    final RM a = linearSystem.getA();
    final RM b = linearSystem.getB();
    final RM c = linearSystem.getC();
    
    final ContinuousLinearDynamicSystem<RS,RM,CS,CM> newSystem = new ContinuousLinearDynamicSystem<>(a, b, c, this.sunit);
    newSystem.setInitialState(((ContinuousLinearDynamicSystem<RS,RM,CS,CM>)system).getInitialState());
    return newSystem;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected boolean replaceDynamicSystemList(final SystemOperator<RS,RM,CS,CM> oldSystem, final SystemOperator<RS,RM,CS,CM> newSystem) {
    final int index = this.continuousDynamicSystems.indexOf((ContinuousDynamicSystem<RS,RM,CS,CM>)oldSystem);
    if (index == -1) {
      return false;
    }
    this.continuousDynamicSystems.set(index, (ContinuousDynamicSystem<RS,RM,CS,CM>)newSystem);
    return true;
  }
}