Cov.java
/*
* $Id: Cov.java,v 1.18 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;
import org.mklab.nfc.scalar.DoubleNumber;
/**
* 分散を求めるクラスです。
*
* <p>Covariance
*
* @author koga
* @version $Revision: 1.18 $
* @see org.mklab.tool.matrix.Corrcoef
*/
public class Cov {
/**
* ベクトル <code>x</code> の成分の分散を求めます。
*
* @param x データ
* @return 自己分散 (Covariance)
*/
public static DoubleNumber cov(DoubleMatrix x) {
return covColumnWise(x.reshape(1, x.getRowSize() * x.getColumnSize())).getElement(1, 1);
}
/**
* cov([x y])を返します。
*
* @param x データ1
* @param y データ2
* @return 共分散 (Covariance)
*/
public static DoubleNumber cov(DoubleMatrix x, DoubleMatrix y) {
DoubleMatrix z = Makecolv.makecolv(x).appendRight(Makecolv.makecolv(y));
return covColumnWise(z.reshape(1, z.getRowSize() * z.getColumnSize())).getElement(1, 1);
}
/**
* もし<code>x</code> が行毎データが並ぶ行列なら、分散行列を返します。
*
* <p><code>diag_vec(cov_col(x))</code> は、各列の分散が並ぶベクトルであり、 <code>sqrt(diag_vec(cov_col(x)))</code> は、標準偏差です。
*
* @param x データ
* @return 自己分散 (Covariance)
*/
public static DoubleMatrix covColumnWise(DoubleMatrix x) {
int rowSize = x.getRowSize();
int columnSize = x.getColumnSize();
DoubleMatrix X;
if (Math.min(rowSize, columnSize) == 1) {
X = Makecolv.makecolv(x);
} else {
X = x;
}
rowSize = X.getRowSize();
X = X.subtract(x.createOnes(rowSize, 1).multiply(X.sumColumnWise().divide(rowSize)));
DoubleMatrix cv;
if (rowSize == 1) {
cv = x.createZero(1, 1);
} else {
cv = X.conjugateTranspose().multiply(X).divide(rowSize - 1);
}
return cv;
}
/**
* @param x データ1
* @param y データ2
* @return 共分散 (Covariance)
*/
public static DoubleMatrix covColumnWise(DoubleMatrix x, DoubleMatrix y) {
int rowSize = x.getRowSize();
int columnSize = x.getColumnSize();
if (rowSize != y.getRowSize() || columnSize != y.getColumnSize()) {
throw new IllegalArgumentException(Messages.getString("Cov.0")); //$NON-NLS-1$
}
if (rowSize != 1 && columnSize != 1) {
throw new IllegalArgumentException(Messages.getString("Cov.1")); //$NON-NLS-1$
}
DoubleMatrix X = Makecolv.makecolv(x).appendRight(Makecolv.makecolv(y));
rowSize = X.getRowSize();
X = X.subtract(x.createOnes(rowSize, 1).multiply(X.sumColumnWise().divide(rowSize)));
if (rowSize == 1) {
return x.createZero(1, 1);
}
return X.conjugateTranspose().multiply(X).divide(rowSize - 1);
}
/**
* もし <code>x</code> が、列毎にデータ並ぶ行列なら、分散行列を返します。
*
* <p><code>diag_vec(cov_row(x))</code> は、各行の分散が並ぶベクトルであり、 <code>sqrt(diag_vec(cov_row(x)))</code> は、標準偏差です。
*
* @param x データ
* @return 自己分散 (Covariance)
*/
public static DoubleMatrix covRowWise(DoubleMatrix x) {
return covColumnWise(x.transpose()).transpose();
}
/**
* @param x データ1
* @param y データ2
* @return 共分散 (Covariance)
*/
public static DoubleMatrix covRowWise(DoubleMatrix x, DoubleMatrix y) {
return covColumnWise(x, y).transpose();
}
}