Cdf2rdf.java
/*
* $Id: Cdf2rdf.java,v 1.20 2008/03/26 14:31:23 koga Exp $
*
* Copyright (C) 2004 Koga Laboratory. All rights reserved.
*/
package org.mklab.tool.matrix;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.mklab.nfc.matrix.DoubleComplexMatrix;
import org.mklab.nfc.matrix.DoubleMatrix;
import org.mklab.nfc.matrix.IntMatrix;
import org.mklab.nfc.scalar.DoubleComplexNumber;
/**
* 複素対角行列から実ブロック対角行列を求めるクラスです。
*
* <p>Complex diagonal form to real diagonal form
*
* @author koga
* @version $Revision: 1.20 $
*/
public class Cdf2rdf {
/**
* 複素対角行列を実ブロック対角行列に変換します。
*
* <p>与えられた複素対角行列 <code>Dc</code> の対角成分について、複素共役対は離れずに並んでいて、行列 <code>Vc</code> には、固有値に対応する固有ベクトルが含まれていなければなりません。
*
* @param Vc 固有ベクトルからなる行列
* @param Dc 固有値が対角に並ぶ対角行列
* @return 実ブロック対角行列 (real diagonal form)
*/
public static List<DoubleMatrix> cdf2rdf(DoubleComplexMatrix Vc, DoubleComplexMatrix Dc) {
final DoubleComplexNumber j = new DoubleComplexNumber(0,1);
final DoubleComplexMatrix jj = j.createGrid(new DoubleComplexNumber[] {j.createUnit(), j.createUnit()}).appendDown(j.createGrid(new DoubleComplexNumber[] {j, j.unaryMinus()}));
final DoubleComplexMatrix T = jj.createUnit(Dc.getRowSize());
IntMatrix idx = Dc.vectorToDiagonal().getImaginaryPart().transpose().compareElementWise(".!=", 0).find(); //$NON-NLS-1$
final int n = idx.length();
idx = idx.getSubVector(1, n, 2);
for (int k = 1; k <= n; k++) {
int i = idx.getIntElement(k);
T.setSubMatrix(i, i + 1, i, i + 1, jj);
}
final DoubleMatrix Vr = Vc.divide(T).getRealPart();
final DoubleMatrix Dr = T.multiply(Dc).divide(T).getRealPart();
return new ArrayList<>(Arrays.asList(new DoubleMatrix[] {Vr, Dr}));
}
}