DoubleSystemSolver.java

/*
 * Created on 2008/11/19
 * Copyright (C) 2008 Koga Laboratory. All rights reserved.
 *
 */
package org.mklab.tool.control.system;

import org.mklab.nfc.matrix.DoubleMatrix;
import org.mklab.nfc.ode.DoubleAlgebraicEquationSolver;
import org.mklab.nfc.ode.DoubleContinuousAlgebraicSystem;
import org.mklab.nfc.ode.DoubleContinuousDiscreteAlgebraicSystem;
import org.mklab.nfc.ode.DoubleDifferenceEquationSolver;
import org.mklab.nfc.ode.DoubleDifferenceSystem;
import org.mklab.nfc.ode.DoubleDifferentialDifferenceSystem;
import org.mklab.nfc.ode.DoubleDifferentialEquationAutoSolver;
import org.mklab.nfc.ode.DoubleDifferentialEquationSolver;
import org.mklab.nfc.ode.DoubleDiscreteAlgebraicSystem;
import org.mklab.nfc.ode.DoubleEquationSolver;
import org.mklab.nfc.ode.DoubleExplicitDifferentialSystem;
import org.mklab.nfc.ode.DoubleImplicitDifferentialEquationSolver;
import org.mklab.nfc.ode.DoubleImplicitDifferentialSystem;
import org.mklab.nfc.ode.SolverStopException;
import org.mklab.tool.control.system.continuous.DoubleContinuousExplicitDynamicSystem;
import org.mklab.tool.control.system.continuous.DoubleContinuousImplicitDynamicSystem;
import org.mklab.tool.control.system.continuous.DoubleContinuousStaticSystem;
import org.mklab.tool.control.system.discrete.DoubleDiscreteDynamicSystem;
import org.mklab.tool.control.system.discrete.DoubleDiscreteStaticSystem;
import org.mklab.tool.control.system.sampled.DoubleSampledDataDynamicSystem;
import org.mklab.tool.control.system.sampled.DoubleSampledDataStaticSystem;


/**
 * {@link SystemOperator}で表されるシステムの時間応答を求めるクラスです。
 * 
 * @author koga
 * @version $Revision$, 2008/11/19
 */
public class DoubleSystemSolver {

  /** 方程式のソルバー */
  private DoubleEquationSolver solver;

  /**
   * 新しく生成された<code>SystemSolver</code>オブジェクトを初期化します。
   * 
   * @param solver 方程式のソルバー
   */
  public DoubleSystemSolver(final DoubleEquationSolver solver) {
    this.solver = solver;
  }

  /**
   * 固定刻み幅でシミュレーション計算を行います。
   * 
   * @param system シミュレーション対象
   * @param t0 シミュレーション開始時刻
   * @param t1 シミュレーション終了時刻
   * @exception SolverStopException ソルバーが停止された場合
   */
  public void solve(DoubleSystemOperator system, double t0, double t1) throws SolverStopException {
    system.initialize();
    
    if (system instanceof DoubleSampledDataStaticSystem && this.solver instanceof DoubleAlgebraicEquationSolver) {
      ((DoubleAlgebraicEquationSolver)this.solver).solve((DoubleContinuousDiscreteAlgebraicSystem)system, t0, t1);
      return;
    }

    if (system instanceof DoubleContinuousStaticSystem && this.solver instanceof DoubleAlgebraicEquationSolver) {
      ((DoubleAlgebraicEquationSolver)this.solver).solve((DoubleContinuousAlgebraicSystem)system, t0, t1);
      return;
    }

    if (system instanceof DoubleDiscreteStaticSystem && this.solver instanceof DoubleAlgebraicEquationSolver) {
      ((DoubleAlgebraicEquationSolver)this.solver).solve((DoubleDiscreteAlgebraicSystem)system, t0, t1);
      return;
    }

    if (system instanceof DoubleDiscreteDynamicSystem && this.solver instanceof DoubleDifferenceEquationSolver) {
      DoubleMatrix xd0 = ((DoubleDiscreteDynamicSystem)system).getInitialState();
      ((DoubleDifferenceEquationSolver)this.solver).solve((DoubleDifferenceSystem)system, t0, t1, xd0);
      return;
    }

    if (system instanceof DoubleContinuousExplicitDynamicSystem && this.solver instanceof DoubleDifferentialEquationSolver) {
      final DoubleMatrix xc0 = ((DoubleContinuousExplicitDynamicSystem)system).getInitialState();
      ((DoubleDifferentialEquationSolver)this.solver).solve((DoubleExplicitDifferentialSystem)system, t0, t1, xc0);
      return;
    }
    
    if (system instanceof DoubleContinuousImplicitDynamicSystem && this.solver instanceof DoubleDifferentialEquationSolver) {
      final DoubleMatrix xc0 = ((DoubleContinuousImplicitDynamicSystem)system).getInitialState();
      ((DoubleImplicitDifferentialEquationSolver)this.solver).solve((DoubleImplicitDifferentialSystem)system, t0, t1, xc0);
      return;
    }

    if (system instanceof DoubleSampledDataDynamicSystem && this.solver instanceof DoubleDifferentialEquationSolver) {
      final DoubleMatrix xc0 = ((DoubleSampledDataDynamicSystem)system).getContinuousInitialState();
      final DoubleMatrix xd0 = ((DoubleSampledDataDynamicSystem)system).getDiscreteInitialState();
      ((DoubleDifferentialEquationSolver)this.solver).solve((DoubleDifferentialDifferenceSystem)system, t0, t1, xc0, xd0);
      return;
    }

    throw new IllegalArgumentException(Messages.getString("SystemSolver.0")); //$NON-NLS-1$
  }

  /**
   * 指定された許容誤差でシミュレーション計算を行います。
   * 
   * @param system シミュレーション対象
   * @param t0 シミュレーション開始時刻
   * @param t1 シミュレーション終了時刻
   */
  public void solveAuto(DoubleSystemOperator system, double t0, double t1) {
    system.initialize();

    if (system instanceof DoubleContinuousExplicitDynamicSystem && this.solver instanceof DoubleDifferentialEquationAutoSolver) {
      final DoubleMatrix xc0 = ((DoubleContinuousExplicitDynamicSystem)system).getInitialState();
      ((DoubleDifferentialEquationAutoSolver)this.solver).solveAuto((DoubleExplicitDifferentialSystem)system, t0, t1, xc0);
      return;
    }
    
    if (system instanceof DoubleContinuousImplicitDynamicSystem && this.solver instanceof DoubleDifferentialEquationAutoSolver) {
      final DoubleMatrix xc0 = ((DoubleContinuousImplicitDynamicSystem)system).getInitialState();
      ((DoubleImplicitDifferentialEquationSolver)this.solver).solveAuto((DoubleImplicitDifferentialSystem)system, t0, t1, xc0);
      return;
    }

    if (system instanceof DoubleSampledDataDynamicSystem && this.solver instanceof DoubleDifferentialEquationAutoSolver) {
      final DoubleMatrix xc0 = ((DoubleSampledDataDynamicSystem)system).getContinuousInitialState();
      final DoubleMatrix xd0 = ((DoubleSampledDataDynamicSystem)system).getDiscreteInitialState();
      ((DoubleDifferentialEquationAutoSolver)this.solver).solveAuto((DoubleDifferentialDifferenceSystem)system, t0, t1, xc0, xd0);
      return;
    }

    throw new IllegalArgumentException(Messages.getString("SystemSolver.1")); //$NON-NLS-1$
  }
}