逆行列,疑似逆行列

行列 (Matrix/ComplexMatrix) A が正則の場合には A.inverse() で逆行列が求められる.非正則の場合には A.pseudo_inverse() で疑似逆行列(ムーア・ペンローズ型の一般逆行列)が求められる.
数学的知識については以下のリンク/書籍を参照.

A.inverse() / A.pseudo_inverse() は const メンバ関数であり,自身を変更しない ことに注意.

逆行列

逆行列の例:

  Matrix A(3,3);
  A(0,0)=1.0; A(0,1)=2.0;  A(0,2)=3.0;
  A(1,0)=2.0; A(1,1)=-1.0; A(1,2)=1.0;
  A(2,0)=4.0; A(2,1)=3.0;  A(2,2)=2.0;
  cout<<"A="<<endl<<A;
  cout<<"A.inverse()="<<endl<< A.inverse();
  cout<<"A * A.inverse()="<<endl<< A * A.inverse();

結果:

  A=
    1 2 3
    2 -1 1
    4 3 2
  A.inverse()=
    -0.2 0.2 0.2
    -0 -0.4 0.2
    0.4 0.2 -0.2
  A * A.inverse()=
    1 1.11022e-16 -1.11022e-16
    0 1           -1.11022e-16
    0 0           1

逆行列計算時のエラー

逆行列の計算に失敗したときにエラーを出力させるには, int info; A.inverse(info) のようにする.ここで整数 info が 0 なら逆行列の計算に成功,それ以外(-1 になるようだ)だと失敗したと判断できる.例:

  Matrix A(3,3);
  A(0,0)=1.0; A(0,1)=2.0;  A(0,2)=3.0;
  A(1,0)=2.0; A(1,1)=-1.0; A(1,2)=1.0;
  A(2,0)=4.0; A(2,1)=3.0;  A(2,2)=2.0;
  int info;
  cout<<"A="<<endl<<A;
  cout<<"A.inverse(info)="<<endl<< A.inverse(info);
  cout<<"info= "<<info<<endl;
  cout<<"A.fill(0.0, 0,1, 2,1)="<<endl<< A.fill(0.0, 0,1, 2,1);
  cout<<"A.inverse(info)="<<endl<< A.inverse(info);
  cout<<"info= "<<info<<endl;

結果:

  A=
    1 2 3
    2 -1 1
    4 3 2
  A.inverse(info)=
    -0.2 0.2 0.2
    -0 -0.4 0.2
    0.4 0.2 -0.2
  info= 0
  A.fill(0.0, 0,1, 2,1)=
    1 0 3
    2 0 1
    4 0 2
  A.inverse(info)=
    1 0 3
    2 0 1
    4 0 2
  info= -1

疑似逆行列

ムーア・ペンローズ型の一般逆行列もサクっと計算できるよ!

  Matrix A(2,3);
  A(0,0)=1.0; A(0,1)=2.0;  A(0,2)=3.0;
  A(1,0)=2.0; A(1,1)=-1.0; A(1,2)=1.0;
  cout<<"A="<<endl<<A;
  cout<<"A.pseudo_inverse()="<<endl<< A.pseudo_inverse();
  cout<<"A * A.pseudo_inverse()="<<endl<< A * A.pseudo_inverse();

結果:

  A=
    1 2 3
    2 -1 1
  A.pseudo_inverse()=
    -1.38778e-17 0.333333
    0.2 -0.266667
    0.2 0.0666667
  A * A.pseudo_inverse()=
    1 0
    0 1