SVD

特異値分解。

bool matrix::SVD(
  matrix&  U,                  // ユニタリ行列
  matrix&  V,                  // ユニタリ行列
  vector&  singular_values      // 特異値ベクトル
  );

パラメータ

U

 [out] 左特異ベクトルから構成される、次数mのユニタリ行列

V

[out] 右特異ベクトルから構成される、次数nのユニタリ行列

singular_values

[out] 特異値

戻り値

成功の場合はtrue、それ以外の場合はfalse

matrix a= {{0, 1, 2, 3, 4, 5, 6, 7, 8}};
a=a-4;
Print("matrix a \n", a);
a.Reshape(3, 3);
matrix b=a;
Print("matrix b \n", b);
//--- SVD分解を実行する
matrix U, V;
vector singular_values;
b.SVD(U, V, singular_values);
Print("U \n", U);
Print("V \n", V);
Print("singular_values = ", singular_values);
 
// チェックブロック
//--- U * 単対角 * V = A
matrix matrix_s;
matrix_s.Diag(singular_values);
Print("matrix_s \n", matrix_s);
matrix matrix_vt=V.Transpose();
Print("matrix_vt \n", matrix_vt);
matrix matrix_usvt=(U.MatMul(matrix_s)).MatMul(matrix_vt);
Print("matrix_usvt \n", matrix_usvt);
 
ulong errors=(int)b.Compare(matrix_usvt, 1e-9);
double res=(errors==0);
Print("errors=", errors);
 
//---- 他のチェック
matrix U_Ut=U.MatMul(U.Transpose());
Print("U_Ut \n", U_Ut);
Print("Ut_U \n", (U.Transpose()).MatMul(U));
 
matrix vt_V=matrix_vt.MatMul(V);
Print("vt_V \n", vt_V);
Print("V_vt \n", V.MatMul(matrix_vt));
 
 /*
matrix a
 [[-4,-3,-2,-1,0,1,2,3,4]]
matrix b
 [[-4,-3,-2]
  [-1,0,1]
  [2,3,4]]
U
 [[-0.7071067811865474,0.5773502691896254,0.408248290463863]
  [-6.827109697437648e-17,0.5773502691896253,-0.8164965809277256]
  [0.7071067811865472,0.5773502691896255,0.4082482904638627]]
V
 [[0.5773502691896258,-0.7071067811865474,-0.408248290463863]
  [0.5773502691896258,1.779939029415334e-16,0.8164965809277258]
  [0.5773502691896256,0.7071067811865474,-0.408248290463863]]
singular_values = [7.348469228349533,2.449489742783175,3.277709923350408e-17]
 
matrix_s
 [[7.348469228349533,0,0]
  [0,2.449489742783175,0]
  [0,0,3.277709923350408e-17]]
matrix_vt
 [[0.5773502691896258,0.5773502691896258,0.5773502691896256]
  [-0.7071067811865474,1.779939029415334e-16,0.7071067811865474]
  [-0.408248290463863,0.8164965809277258,-0.408248290463863]]
matrix_usvt
 [[-3.999999999999997,-2.999999999999999,-2]
  [-0.9999999999999981,-5.977974170712231e-17,0.9999999999999974]
  [2,2.999999999999999,3.999999999999996]]
errors=0
 
U_Ut
 [[0.9999999999999993,-1.665334536937735e-16,-1.665334536937735e-16]
  [-1.665334536937735e-16,0.9999999999999987,-5.551115123125783e-17]
  [-1.665334536937735e-16,-5.551115123125783e-17,0.999999999999999]]
Ut_U
 [[0.9999999999999993,-5.551115123125783e-17,-1.110223024625157e-16]
  [-5.551115123125783e-17,0.9999999999999987,2.498001805406602e-16]
  [-1.110223024625157e-16,2.498001805406602e-16,0.999999999999999]]
vt_V
 [[1,-5.551115123125783e-17,0]
  [-5.551115123125783e-17,0.9999999999999996,1.110223024625157e-16]
  [0,1.110223024625157e-16,0.9999999999999996]]
V_vt
 [[0.9999999999999999,1.110223024625157e-16,1.942890293094024e-16]
  [1.110223024625157e-16,0.9999999999999998,1.665334536937735e-16]
  [1.942890293094024e-16,1.665334536937735e-16,0.9999999999999996]
 */
}