AdjacencyMatrixUtil.java

/*
 * $Id: AdjacencyMatrixUtil.java,v 1.31 2008/07/15 15:27:15 koga Exp $
 *
 * Copyright (C) 2004-2005 Koga Laboratory. All rights reserved.
 *
 */

package org.mklab.tool.control.system;

/**
 * {@link AdjacencyMatrix}クラスのユーティリティクラスです。
 * 
 * @author Koga Laboratory
 * @version $Revision: 1.31 $
 */
public class AdjacencyMatrixUtil {

  /**
   * 左上の存在する的システムの数を表すクラスです。
   * 
   * @author koga
   */
  static class NumberOfLeftUpperSystem {

    /** 左側に存在するシステムの数 */
    public int numberInLeft = 0;

    /** 上側に存在するシステムの数 */
    public int numberInUpper = 0;
  }



//  /**
//   * 積分器(または1サンプル遅れ器)が存在する行番号を返します。
//   * 
//   * @param matrix 隣接行列
//   * @param column 調べる列
//   * @return 積分器(または1サンプル遅れ器)が存在する行番号、積分器(または1サンプル遅れ器)が存在しない場合、-1
//   */
//  static int findIntegratorOrUnitDelayInColumn(final SystemOperator[][] matrix, final int column) {
//    final int rowSize = matrix.length;
//
//    for (int row = 0; row < rowSize; row++) {
//      SystemOperator system = matrix[row][column];
//      if (system instanceof IntegratorSystem) {
//        return row;
//      }
//      if (system instanceof UnitDelaySystem) {
//        return row;
//      }
//    }
//
//    return -1;
//  }




//  /**
//   * <code>column</code>列の全ての成分が零又は定数システムであるか判定します。
//   * 
//   * @param matrix 調べる配列
//   * @param column 調べる列番号
//   * @param onlyConstant 定数のみを縮約するならばtrue
//   * @return <code>column</code>列の全ての成分が零又は定数システムならばtrue、そうでなければfalse
//   */
//  static boolean isAllConstantOrZeroInColumn(final SystemOperator[][] matrix, final int column, final boolean onlyConstant) {
//    final int rowSize = matrix.length;
//
//    for (int k = 0; k < rowSize; k++) {
//      if (matrix[k][column] != ZeroSystem.getInstance()) {
//        if ((matrix[k][column] instanceof ConstantSystem) == false) {
//          return false;
//        }
//        if (onlyConstant && ((ConstantSystem)matrix[k][column]).isVariable()) {
//          return false;
//        }
//      }
//    }
//
//    return true;
//  }





//  /**
//   * <code>column</code>列を含めて左側に存在する指定された型のシステムの数、 左上対角ブロック(0,0,<code>row</code>,<code>row</code>)に存在するを指定された型のシステムの数を調べます。
//   * 
//   * @param matrix 対象となる行列
//   * @param row 行番号
//   * @param column 列番号
//   * @param klass クラスの型
//   * @return 指定された位置(<code>row</code>,<code>column</code>)を含めて左上に存在する指定された型のシステムの数
//   */
//  static NumberOfLeftUpperSystem findSystemInLeftUpper(final SystemOperator[][] matrix, final int row, final int column, final Class<?> klass) {
//    final int size = matrix.length;
//    NumberOfLeftUpperSystem numbers = new NumberOfLeftUpperSystem();
//
//    for (int i = 0; i < size; i++) {
//      for (int j = 0; j <= column; j++) {
//        if (klass.isInstance(matrix[i][j])) {
//          numbers.numberInLeft++;
//          break;
//        }
//      }
//    }
//
//    for (int i = 0; i <= row; i++) {
//      for (int j = 0; j <= row; j++) {
//        if (klass.isInstance(matrix[i][j])) {
//          numbers.numberInUpper++;
//          break;
//        }
//      }
//    }
//
//    return numbers;
//  }





//  /**
//   * 線形動的システムの状態空間表現による隣接行列を生成します。
//   * 
//   * @param system 線形動的システム
//   * 
//   * @return 線形動的システムの状態空間表現による隣接行列
//   */
//  static SystemOperator[][] createLinearDynamicSystemBlockMatrix(final SystemOperator system) {
//    final SystemOperator[][] matrix = new SystemOperator[4][4];
//
//    AdjacencyMatrixUtil.setZeroSystemToNullElement(matrix);
//
//    final LinearSystemOperator linearSystem = (LinearSystemOperator)system;
//    final String format = linearSystem.getLinearSystem().getFormat();
//
//    if (system instanceof IntegratorSystem) {
//      matrix[1][2] = ZeroSystem.getInstance();
//      matrix[0][2] = new UnitSystem(linearSystem.getA().getRowSize());
//      matrix[1][3] = new UnitSystem(linearSystem.getA().getRowSize());
//      matrix[0][3] = ZeroSystem.getInstance();
//
//      matrix[2][1] = new IntegratorSystem(system.getStateSize());
//      ((IntegratorSystem)matrix[2][1]).setTag(linearSystem.getTag());
//      ((IntegratorSystem)matrix[2][1]).setStateNumber(((DynamicSystem)system).getStateNumber());
//
//    } else if (system.getLinearSystem().isProper() == false) {
//
//      // A取得
//      matrix[1][2] = new ConstantSystem(linearSystem.getA());
//      if (linearSystem.hasVariableA()) {
//        // ((ConstantSystem)matrix[1][2]).setExpression("A_" + linearSystem.getTag());
//        // //$NON-NLS-1$
//        ((ConstantSystem)matrix[1][2]).setExpression(linearSystem.getTag() + "_A"); //$NON-NLS-1$
//      } else {
//        final DoubleMatrix value = linearSystem.getA();
//        ((ConstantSystem)matrix[1][2]).setExpression(toMmString(value, format));
//      }
//      ((ConstantSystem)matrix[1][2]).setTag(linearSystem.getTag());
//      ((ConstantSystem)matrix[1][2]).setVariable(linearSystem.hasVariableA());
//
//      // B取得
//      matrix[0][2] = new ConstantSystem(linearSystem.getB());
//      if (linearSystem.hasVariableB()) {
//        // ((ConstantSystem)matrix[0][2]).setExpression("B_" + linearSystem.getTag());
//        // //$NON-NLS-1$
//        ((ConstantSystem)matrix[0][2]).setExpression(linearSystem.getTag() + "_B"); //$NON-NLS-1$
//      } else {
//        final DoubleMatrix value = linearSystem.getB();
//        ((ConstantSystem)matrix[0][2]).setExpression(toMmString(value, format));
//      }
//      ((ConstantSystem)matrix[0][2]).setTag(linearSystem.getTag());
//      ((ConstantSystem)matrix[0][2]).setVariable(linearSystem.hasVariableB());
//
//      // C取得
//      matrix[1][3] = new ConstantSystem(linearSystem.getC());
//      if (linearSystem.hasVariableC()) {
//        // ((ConstantSystem)matrix[1][3]).setExpression("C_" + linearSystem.getTag());
//        // //$NON-NLS-1$
//        ((ConstantSystem)matrix[1][3]).setExpression(linearSystem.getTag() + "_C"); //$NON-NLS-1$
//      } else {
//        final DoubleMatrix value = linearSystem.getC();
//        ((ConstantSystem)matrix[1][3]).setExpression(toMmString(value, format));
//      }
//      ((ConstantSystem)matrix[1][3]).setTag(linearSystem.getTag());
//      ((ConstantSystem)matrix[1][3]).setVariable(linearSystem.hasVariableC());
//
//      // D取得
//      final DoubleMatrix value = linearSystem.getD();
//      if (value.isZero()) {
//        matrix[0][3] = ZeroSystem.getInstance();
//      } else {
//        matrix[0][3] = new ConstantSystem(linearSystem.getD());
//        if (linearSystem.hasVariableD()) {
//          // ((ConstantSystem)matrix[0][3]).setExpression("D_" + linearSystem.getTag());
//          // //$NON-NLS-1$
//          ((ConstantSystem)matrix[0][3]).setExpression(linearSystem.getTag() + "_D"); //$NON-NLS-1$
//        } else {
//          // final DoubleMatrix value = linearSystem.getD();
//          ((ConstantSystem)matrix[0][3]).setExpression(toMmString(value, format));
//        }
//        ((ConstantSystem)matrix[0][3]).setTag(linearSystem.getTag());
//        ((ConstantSystem)matrix[0][3]).setVariable(linearSystem.hasVariableD());
//      }
//
//      // E取得
//      final ConstantSystem e = new ConstantSystem(((ImproperLinearSystem)linearSystem.getLinearSystem()).getE());
//      // e.setExpression("E_" + linearSystem.getTag()); //$NON-NLS-1$
//      e.setExpression(linearSystem.getTag() + "_E"); //$NON-NLS-1$
//      e.setTag(linearSystem.getTag());
//      e.setVariable(linearSystem.hasVariableE());
//      matrix[2][2] = e.unaryMinus().add(new UnitSystem(e.getGain().getRowSize()));
//
//      // matrix[2][1] = new IntegratorSystem(system.getStateSize());
//      matrix[2][1] = new IntegratorSystem(linearSystem.getA().getColumnSize());
//      ((IntegratorSystem)matrix[2][1]).setTag("x_" + linearSystem.getTag()); //$NON-NLS-1$
//      ((IntegratorSystem)matrix[2][1]).setStateNumber(((DynamicSystem)system).getStateNumber());
//    } else if (system instanceof UnitDelaySystem) {
//      matrix[1][2] = ZeroSystem.getInstance();
//      matrix[0][2] = new UnitSystem(linearSystem.getA().getRowSize());
//      matrix[1][3] = new UnitSystem(linearSystem.getA().getRowSize());
//      matrix[0][3] = ZeroSystem.getInstance();
//
//      matrix[2][1] = new UnitDelaySystem(system.getStateSize());
//      ((UnitDelaySystem)matrix[2][1]).setTag(linearSystem.getTag());
//      ((UnitDelaySystem)matrix[2][1]).setStateNumber(((DynamicSystem)system).getStateNumber());
//    } else {
//      // A取得
//      matrix[1][2] = new ConstantSystem(linearSystem.getA());
//      if (linearSystem.hasVariableA()) {
//        // ((ConstantSystem)matrix[1][2]).setExpression("A_" + linearSystem.getTag());
//        // //$NON-NLS-1$
//        ((ConstantSystem)matrix[1][2]).setExpression(linearSystem.getTag() + "_A"); //$NON-NLS-1$
//      } else {
//        final DoubleMatrix value = linearSystem.getA();
//        ((ConstantSystem)matrix[1][2]).setExpression(toMmString(value, format));
//      }
//      ((ConstantSystem)matrix[1][2]).setTag(linearSystem.getTag());
//      ((ConstantSystem)matrix[1][2]).setVariable(linearSystem.hasVariableA());
//
//      // B取得
//      matrix[0][2] = new ConstantSystem(linearSystem.getB());
//      if (linearSystem.hasVariableB()) {
//        // ((ConstantSystem)matrix[0][2]).setExpression("B_" + linearSystem.getTag());
//        // //$NON-NLS-1$
//        ((ConstantSystem)matrix[0][2]).setExpression(linearSystem.getTag() + "_B"); //$NON-NLS-1$
//      } else {
//        final DoubleMatrix value = linearSystem.getB();
//        ((ConstantSystem)matrix[0][2]).setExpression(toMmString(value, format));
//      }
//      ((ConstantSystem)matrix[0][2]).setTag(linearSystem.getTag());
//      ((ConstantSystem)matrix[0][2]).setVariable(linearSystem.hasVariableB());
//
//      // C取得
//      matrix[1][3] = new ConstantSystem(linearSystem.getC());
//      if (linearSystem.hasVariableC()) {
//        // ((ConstantSystem)matrix[1][3]).setExpression("C_" + linearSystem.getTag());
//        // //$NON-NLS-1$
//        ((ConstantSystem)matrix[1][3]).setExpression(linearSystem.getTag() + "_C"); //$NON-NLS-1$
//      } else {
//        final DoubleMatrix value = linearSystem.getC();
//        ((ConstantSystem)matrix[1][3]).setExpression(toMmString(value, format));
//      }
//      ((ConstantSystem)matrix[1][3]).setTag(linearSystem.getTag());
//      ((ConstantSystem)matrix[1][3]).setVariable(linearSystem.hasVariableC());
//
//      // D取得
//      final DoubleMatrix value = linearSystem.getD();
//      if (value.isZero()) {
//        matrix[0][3] = ZeroSystem.getInstance();
//      } else {
//        matrix[0][3] = new ConstantSystem(linearSystem.getD());
//        if (linearSystem.hasVariableD()) {
//          // ((ConstantSystem)matrix[0][3]).setExpression("D_" + linearSystem.getTag());
//          // //$NON-NLS-1$
//          ((ConstantSystem)matrix[0][3]).setExpression(linearSystem.getTag() + "_D"); //$NON-NLS-1$
//        } else {
//          // final DoubleMatrix value = linearSystem.getD();
//          if (value.isZero()) {
//            matrix[0][3] = ZeroSystem.getInstance();
//          }
//          ((ConstantSystem)matrix[0][3]).setExpression(toMmString(value, format));
//        }
//        ((ConstantSystem)matrix[0][3]).setTag(linearSystem.getTag());
//        ((ConstantSystem)matrix[0][3]).setVariable(linearSystem.hasVariableD());
//      }
//      // E取得
//      DoubleMatrix E = linearSystem.getE();
//      if (!E.equals(E.createUnit())) {
//        final ConstantSystem e = new ConstantSystem(E);
//        // e.setExpression("E_" + linearSystem.getTag()); //$NON-NLS-1$
//        e.setExpression(linearSystem.getTag() + "_E"); //$NON-NLS-1$
//        e.setTag(linearSystem.getTag());
//        e.setVariable(linearSystem.hasVariableE());
//        matrix[2][2] = e.unaryMinus().add(new UnitSystem(e.getGain().getRowSize()));
//      }
//      matrix[2][1] = new IntegratorSystem(system.getStateSize());
//      ((IntegratorSystem)matrix[2][1]).setTag("x_" + linearSystem.getTag()); //$NON-NLS-1$
//      ((IntegratorSystem)matrix[2][1]).setStateNumber(((DynamicSystem)system).getStateNumber());
//
//    }
//
//    // IngegralSystem
//    return matrix;
//  }

//  /**
//   * 行列の値をMMフォーマットで返します。
//   * 
//   * @param value 行列の値
//   * @param format フォーマット
//   * @return 行列の値をMMフォーマット
//   */
//  private static String toMmString(final DoubleMatrix value, final String format) {
//    final String expression;
//    if (value.getRowSize() == 1 && value.getColumnSize() == 1) {
//      expression = value.getElement(1, 1).toString(format);
//    } else {
//      expression = ((MatxObject)value).toMmString(format).replaceAll("\\s*", ""); //$NON-NLS-1$ //$NON-NLS-2$
//    }
//    return expression;
//  }




//  /**
//   * 線形動的システムの状態空間表現によるブロックシステムに置き換えます。
//   * 
//   * @param matrix 隣接行列
//   * @return 線形動的システムの状態空間表現をブロックシステムに置き換えた隣接行列
//   */
//  @SuppressWarnings("boxing")
//  static SystemOperator[][] replaceLinearDynamicSystemWithBLockSystem(final SystemOperator[][] matrix) {
//    final SystemOperator[][] newMatrix = AdjacencyMatrixUtil.createClone(matrix);
//
//    final int size = newMatrix.length;
//
//    for (int row = 0; row < size; row++) {
//      for (int column = 0; column < size; column++) {
//        if (newMatrix[row][column] == ZeroSystem.getInstance()) {
//          continue;
//        }
//
//        if (!newMatrix[row][column].isLinear() || !newMatrix[row][column].isDynamic()) {
//          continue;
//        }
//
//        final List<Integer> inputNodes = new ArrayList<>(Arrays.asList(1));
//        final List<Integer> outputNodes = new ArrayList<>(Arrays.asList(4));
//
//        newMatrix[row][column] = new BlockContinuousExplicitDynamicSystem(createLinearDynamicSystemBlockMatrix(newMatrix[row][column]), inputNodes, outputNodes);
//
//      }
//    }
//
//    return newMatrix;
//  }




//  /**
//   * 零システムを「0」、非零システムを「1」で表わした文字列を返します。
//   * 
//   * @param matrix 対象となる行列
//   * @return 零システムを「0」、非零システムを「1」で表わした文字列
//   */
//  static String toByZeroOne(final SystemOperator[][] matrix) {
//    final int size = matrix.length;
//    final StringBuffer ans = new StringBuffer(size);
//
//    for (int row = 0; row < size; row++) {
//      for (int column = 0; column < size; column++) {
//        if (matrix[row][column] == ZeroSystem.getInstance()) {
//          ans.append("0"); //$NON-NLS-1$
//        } else {
//          ans.append("1"); //$NON-NLS-1$
//        }
//      }
//      ans.append(System.getProperty("line.separator")); //$NON-NLS-1$
//    }
//
//    return ans.toString();
//  }
}