DoubleUserDefinedContinuousExplicitDynamicSystem.java

/*
 * Created on 2007/07/16
 * Copyright (C) 2007 Koga Laboratory. All rights reserved.
 *
 */
package org.mklab.tool.control.system.continuous;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.mklab.nfc.matrix.DoubleMatrix;
import org.mklab.nfc.ode.SolverStopException;


/**
 * ユーザ定義連続時間動的システムを表わすクラスです。
 * 
 * @author koga
 * @version $Revision: 1.14 $, 2007/07/16
 */
public class DoubleUserDefinedContinuousExplicitDynamicSystem extends DoubleUserDefinedContinuousDynamicSystem implements DoubleContinuousExplicitDynamicSystem {
  /** M行列 */
  private DoubleMatrix matrixM;
  
  /** システムのM行列を定義したメソッド */
  private Method matrixMFunction;

  /** システムのヤコビ行列を定義したメソッド */
  private Method jacobianMatrixFunction;
  
  /** 微分代数方程式で表せるシステムならばtrue */
  private boolean isDifferentialAlgebraicSystem = false;
  
  /** ヤコビ行列を持っていればtrue */
  private boolean hasJacobianMatrix = false;
  /** 状態と状態の微分の初期値が整合していればtrue */
  private boolean hasConsistentInitialValue = false;

  /**
   * 新しく生成された<code>UserDefinedDynamicSystem</code>オブジェクトを初期化します。
   * 
   * @param obj 呼び出し対象オブジェクト。nullの場合は静的メソッドを参照します
   */
  public DoubleUserDefinedContinuousExplicitDynamicSystem(Object obj) {
    super(obj);
    this.matrixM = DoubleMatrix.unit(getStateSize());
  }

  /**
   * 新しく生成された<code>UserDefinedContinuousDynamicSystem</code>オブジェクトを初期化します。
   */
  public DoubleUserDefinedContinuousExplicitDynamicSystem() {
    this(null);
  }
  
  /**
   * {@inheritDoc}
   */
  @Override
  public DoubleMatrix matrixM() throws SolverStopException {
    try {
      return (DoubleMatrix)this.matrixMFunction.invoke(this.object);
    } catch (IllegalArgumentException e) {
      throw new SolverStopException(e);
    } catch (IllegalAccessException e) {
      throw new SolverStopException(e);
    } catch (InvocationTargetException e) {
      throw new SolverStopException(e.getTargetException());
    } catch (Exception e) {
      throw new SolverStopException(e);
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public DoubleMatrix stateEquation(double t, DoubleMatrix x, DoubleMatrix u) throws SolverStopException {
    try {
      return (DoubleMatrix)this.stateFunction.invoke(this.object, Double.valueOf(t), x, u);
    } catch (IllegalArgumentException e) {
      throw new SolverStopException(e);
    } catch (IllegalAccessException e) {
      throw new SolverStopException(e);
    } catch (InvocationTargetException e) {
      throw new SolverStopException(e.getTargetException());
    } catch (Exception e) {
      throw new SolverStopException(e);
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public DoubleMatrix getJacobianMatrix(double t, DoubleMatrix x, DoubleMatrix u) {
    try {
      return (DoubleMatrix)this.jacobianMatrixFunction.invoke(this.object, Double.valueOf(t), x, u);
    } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * M行列を定義したメソッドを設定します。
   * 
   * @param method M行列を定義したメソッド
   * @throws SecurityException メソッドにアクセスする権利が無い場合
   */
  public void setMatrixMFunction(final Method method) throws SecurityException {
    this.matrixMFunction = method;
    this.matrixMFunction.setAccessible(true);
  }
  
  /**
   * ヤコビ行列を定義したメソッドを設定します。
   * 
   * @param method ヤコビ行列を定義したメソッド
   * @throws SecurityException メソッドにアクセスする権利が無い場合
   */
  public void setJacobianMatrixFunction(final Method method) throws SecurityException {
    this.jacobianMatrixFunction = method;
    this.jacobianMatrixFunction.setAccessible(true);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleMatrix differentialEquation(double t, DoubleMatrix x, DoubleMatrix inputOutput) throws SolverStopException {
    final DoubleMatrix u = inputOutput.getRowVectors(1, getInputSize());
    return stateEquation(t, x, u);    
  }
  
  /**
   * Mx'=f(t,x,u)のM行列を設定します。
   * @param matrixM M行列
   */
  public void setMatrixM(DoubleMatrix matrixM) {
    this.matrixM = matrixM;
  }
  
  /**
   * {@inheritDoc}
   */
  public DoubleMatrix getMatrixM() {
    return this.matrixM;
  }

  /**
   * {@inheritDoc}
   */
  public boolean isDifferentialAlgebraicSystem() {
    return this.isDifferentialAlgebraicSystem;
  }

  /**
   * {@inheritDoc}
   */
  public boolean hasJacobianMatrix() {
    return this.hasJacobianMatrix;
  }

  /**
   * {@inheritDoc}
   */
  public boolean hasConsistentInitialValue() {
    return this.hasConsistentInitialValue;
  }
  
  /**
   * 状態と状態の微分の初期値が整合するか設定します。
   * @param hasConsistentInitialValue 状態と状態の微分の初期値が整合すればtrue
   */
  public void setHasConsistentInitialValue(boolean hasConsistentInitialValue) {
    this.hasConsistentInitialValue = hasConsistentInitialValue;
  }

  /**
   * ヤコビ行列を持っているか設定します。
   * @param hasJacobianMatrix ヤコビ行列をもっていればtrue
   */
  public void setHasJacobianMatrix(boolean hasJacobianMatrix) {
    this.hasJacobianMatrix = hasJacobianMatrix;
  }
}