コレスキー分解

コレスキー分解 (Cholesky decomposition) の用途: サンプルデータの前処理, Ax = b の数値解,モンテカルロ法,カルマンフィルタなど(一部 Cholesky decomposition - Wikipedia, the free encyclopedia より). 正定値エルミート行列 (実数値行列なら, 正定値対称行列 ) にのみ適用可能.
行列 (Matrix/ComplexMatrix) A に対するコレスキー分解は

  CHOL  chol (const Matrix& A);
  CHOL  chol (const Matrix& A, octave_idx_type& info);
  ComplexCHOL  chol (const ComplexMatrix& A);
  ComplexCHOL  chol (const ComplexMatrix& A, octave_idx_type& info);

によって得られる.ここで CHOL クラス, ComplexCHOL クラス のオブジェクトにはコレスキー分解の結果の行列が代入されている. info は計算後にゼロ以外なら何らかのエラーが発生したことを示すフラグである.

CHOL オブジェクトは以下の public メンバ関数を持つ:

  // コレスキー分解された行列を返す :
  Matrix  chol_matrix (void) const;

liboctave のコレスキー分解は,行列Aを

  A=R'R

となるように分解する.ここで R はコレスキー分解された行列で, chol.chol_matrix() によって取得できる. R' は R の転置行列である.

サンプル:

  Matrix A(4,4);
  stringstream ss (
    "  4.0  2.0  3.0  1.0"
    "  0.0 -1.0  1.0  2.0"
    "  1.0  3.0  2.0  4.0"
    "  0.0 -1.0 -5.0 -4.0"); ss >> A;
  int info;
  cout<<"A="<<endl<<A;
  // CHOL オブジェクトの生成 :
  CHOL  chol (A, info);
  cout<<"info= "<<info<<endl;
  cout<<"chol.chol_matrix()= "<<endl<< chol.chol_matrix();
  cout<<"chol.chol_matrix().transpose()*chol.chol_matrix()= "<<endl
    << chol.chol_matrix().transpose()*chol.chol_matrix();
  // A を正定値対称にする :
  A= A.transpose()*A;
  cout<<"A="<<endl<<A;
  // 再度コレスキー分解 :
  chol= CHOL(A,info);
  cout<<"info= "<<info<<endl;
  cout<<"chol.chol_matrix()= "<<endl<< chol.chol_matrix();
  cout<<"chol.chol_matrix().transpose()*chol.chol_matrix()= "<<endl
    << chol.chol_matrix().transpose()*chol.chol_matrix();

結果:

  A=
    4 2 3 1
    0 -1 1 2
    1 3 2 4
    0 -1 -5 -4
  info= -1
  chol.chol_matrix()=
    2 1 1.5 0.5
    0 -2 1 2
    1 3 2 4
    0 -1 -5 -4
  chol.chol_matrix().transpose()*chol.chol_matrix()=
    5 5 5 5
    5 15 10.5 12.5
    5 10.5 32.25 30.75
    5 12.5 30.75 36.25
  A=
    17 11 14 8
    11 15 16 16
    14 16 39 33
    8 16 33 37
  info= 0
  chol.chol_matrix()=
    4.12311 2.66789 3.3955 1.94029
    0 2.80755 2.47232 3.85515
    0 0 4.62149 3.65263
    0 0 0 2.24309
  chol.chol_matrix().transpose()*chol.chol_matrix()=
    17 11 14 8
    11 15 16 16
    14 16 39 33
    8 16 33 37

前半の行列は対称でも正定値でもないため,コレスキー分解に失敗しているが,後半の行列は正定値対称行列なので,コレスキー分解に成功している.