DiagVec.java

/*
 * $Id: DiagVec.java,v 1.12 2008/07/16 15:40:00 koga Exp $
 * 
 * Copyright (C) 2004 Koga Laboratory. All rights reserved.
 */
package org.mklab.tool.matrix;

import org.mklab.nfc.matrix.DoubleMatrix;


/**
 * 対角行列の対角成分からなるベクトルを求めるクラスです。
 * 
 * <p> Exchange a vector and diagonal elements of a matrix
 * 
 * @author koga
 * @version $Revision: 1.12 $
 * @see org.mklab.tool.matrix.Diag
 */
public class DiagVec {

  /**
   * もし<code>A</code>が正方行列なら、<code>A</code>の対角成分が並ぶ縦 ベクトルを返します。
   * 
   * <p> もし<code>A</code>がベクトルなら、<code>A</code>の成分が対角に並ぶ 対角行列を返します。
   * 
   * @param A 対象となる行列
   * @return (ベクトル又は対角行列) (vector or diagonal matrix)
   */
  public static DoubleMatrix diagVec(DoubleMatrix A) {
    int k = 0;
    return diagVec(A, k);
  }

  /**
   * もし<code>A</code>が正方行列なら、 <code>A</code>の<code>k</code>次対角成分(<code>k  &gt;  0 ? 上側:下側</code>)が並ぶ縦ベクトル を返します。
   * 
   * <p> もし<code>A</code>がベクトルなら、 <code>A</code>の成分が<code>k</code>次(<code>k  &gt;  0 ? 上側:下側</code>)対角成分に並ぶ行列を返します。
   * 
   * @param A_ 対象となる行列
   * @param k 次数
   * @return (ベクトル又は対角行列 ) (vector or diagonal matrix)
   */
  public static DoubleMatrix diagVec(DoubleMatrix A_, int k) {
    if (A_.length() == 0) {
      return A_.createZero(0, 0);
    }

    DoubleMatrix A = A_;

    DoubleMatrix AA;

    final int rowSize = A.getRowSize();
    final int columnSize = A.getColumnSize();

    if (rowSize == 1 || columnSize == 1) {
      DoubleMatrix B = A.vectorToDiagonal();
      int n = A.length();
      if (k > 0) {
        AA = A.createZero(n, k).appendRight(B).appendDown(A.createZero(k, n + k));
      } else if (k < 0) {
        AA = A.createZero(Math.abs(k), n + Math.abs(k)).appendDown(B.appendRight(A.createZero(n, Math.abs(k))));
      } else {
        AA = B;
      }
    } else {
      if (rowSize < columnSize) {
        A = A.getSubMatrix(1, rowSize, 1, rowSize);
      } else if (rowSize > columnSize) {
        A = A.getSubMatrix(1, columnSize, 1, columnSize);
      }

      int n = rowSize;
      if (n - 1 < Math.abs(k)) {
        throw new IllegalArgumentException(Messages.getString("DiagVec.0")); //$NON-NLS-1$
      }

      DoubleMatrix B;
      if (k > 0) {
        B = A.getSubMatrix(1, n - k, k + 1, n);
      } else if (k < 0) {
        B = A.getSubMatrix(Math.abs(k) + 1, n, 1, n - Math.abs(k));
      } else {
        B = A;
      }
      AA = B.diagonalToVector();
    }

    return AA;
  }

}