DoubleBaseContinuousExplicitDynamicSystem.java

/*
 * $Id: BaseContinuousDynamicSystem.java,v 1.21 2008/06/26 10:10:34 koga Exp $
 *
 * Copyright (C) 2004 Koga Laboratory. All rights reserved.
 *
 */

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

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


/**
 * 常微分方程式で表現される連続時間動的システムを表わすクラスです。
 * 
 * @author Koga Laboratory
 * @version $Revision: 1.21 $, 2004/11/09
 */
public abstract class DoubleBaseContinuousExplicitDynamicSystem extends DoubleBaseContinuousDynamicSystem implements DoubleContinuousExplicitDynamicSystem {
  /** M行列 */
  private DoubleMatrix matrixM;
  
  /** ヤコビ行列 */
  private DoubleMatrix jacobian;
  
  /** 微分代数方程式で表せるシステムならばtrue */
  private boolean isDifferentialAlgebraicSystem = false;
  
  /** ヤコビ行列を持っていればtrue */
  private boolean hasJacobianMatrix = false;
  /** 状態と状態の微分の初期値が整合していればtrue */
  private boolean hasConsistentInitialValue = false;

  /**
   * 新しく生成された<code>BaseContinuousDynamicSystem</code>オブジェクトを初期化します。
   * 
   * @param inputSize 入力の数
   * @param outputSize 出力の数
   * @param stateSize 状態の数
   */
  public DoubleBaseContinuousExplicitDynamicSystem(final int inputSize, final int outputSize, final int stateSize) {
    super(inputSize, outputSize, stateSize);
    this.matrixM = DoubleMatrix.unit(stateSize);
    this.jacobian = new DoubleMatrix(stateSize, stateSize);
  }
  
  /**
   * {@inheritDoc}
   */
  @Override
  public int hashCode() {
    final int prime = 31;
    int result = super.hashCode();
    result = prime * result + (this.hasConsistentInitialValue ? 1231 : 1237);
    result = prime * result + (this.hasJacobianMatrix ? 1231 : 1237);
    result = prime * result + (this.isDifferentialAlgebraicSystem ? 1231 : 1237);
    result = prime * result + ((this.jacobian == null) ? 0 : this.jacobian.hashCode());
    result = prime * result + ((this.matrixM == null) ? 0 : this.matrixM.hashCode());
    return result;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean equals(Object obj) {
    if (this == obj) return true;
    if (!super.equals(obj)) return false;
    if (getClass() != obj.getClass()) return false;
    DoubleBaseContinuousExplicitDynamicSystem other = (DoubleBaseContinuousExplicitDynamicSystem)obj;
    if (this.hasConsistentInitialValue != other.hasConsistentInitialValue) return false;
    if (this.hasJacobianMatrix != other.hasJacobianMatrix) return false;
    if (this.isDifferentialAlgebraicSystem != other.isDifferentialAlgebraicSystem) return false;
    if (this.jacobian == null) {
      if (other.jacobian != null) return false;
    } else if (!this.jacobian.equals(other.jacobian)) return false;
    if (this.matrixM == null) {
      if (other.matrixM != null) return false;
    } else if (!this.matrixM.equals(other.matrixM)) return false;
    return true;
  }
  
  /**
   * {@inheritDoc}
   */
  @Override
  public DoubleBaseContinuousExplicitDynamicSystem clone() {
    final DoubleBaseContinuousExplicitDynamicSystem inst = (DoubleBaseContinuousExplicitDynamicSystem)super.clone();
    inst.jacobian = this.jacobian == null ? null : this.jacobian.createClone();
    inst.matrixM = this.matrixM == null ? null : this.matrixM.createClone();
    inst.hasConsistentInitialValue = this.hasConsistentInitialValue;
    inst.hasJacobianMatrix = this.hasJacobianMatrix;
    inst.isDifferentialAlgebraicSystem = this.isDifferentialAlgebraicSystem;
    return inst;
  }

  /**
   * {@inheritDoc}
   */
  final public DoubleMatrix differentialEquation(final double t, final DoubleMatrix x, final DoubleMatrix inputOutput) throws SolverStopException {
    final DoubleMatrix u = inputOutput.getRowVectors(1, getInputSize());
    return stateEquation(t, x, u);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleMatrix matrixM() throws SolverStopException {
    throw new SolverStopException(Messages.getString("BaseContinuousDynamicSystem.2")); //$NON-NLS-1$
  }
  
  /**
   * {@inheritDoc}
   */
  public DoubleMatrix getMatrixM() {
    return this.matrixM;
  }

  /**
   * {@inheritDoc}
   */
  
  public DoubleMatrix getJacobianMatrix(double t, DoubleMatrix x, DoubleMatrix u) {
    return this.jacobian;
  }
  
  
  /**
   * Mx'=f(t,x,u)のM行列を設定します。
   * @param matrixM M行列
   */
  public void setMatrixM(DoubleMatrix matrixM) {
    this.matrixM = matrixM;
  }
 
  /**
   * {@inheritDoc}
   */
  public boolean isDifferentialAlgebraicSystem() {
    return this.isDifferentialAlgebraicSystem;
  }
  
  /**
   * 微分代数方程式で表されるシステムであるか設定します。
   * @param isDifferentialAlgebraicSystem 微分代数方程式で表されるシステムならばtrue
   */
  protected void setDifferentialAlgebraicSystem(boolean isDifferentialAlgebraicSystem) {
    this.isDifferentialAlgebraicSystem = isDifferentialAlgebraicSystem;
  }
  
  /**
   * 状態と状態の微分の初期値が整合するか設定します。
   * @param hasConsistentInitialValue 状態と状態の微分の初期値が整合すればtrue
   */
  public void setHasConsistentInitialValue(boolean hasConsistentInitialValue) {
    this.hasConsistentInitialValue = hasConsistentInitialValue;
  }

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

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

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

}