SVD

Вычисляет разложение по сингулярным значениям.

bool matrix::SVD(
  matrix&  U,                   // унитарная матрица
  matrix&  V,                   // унитарная матрица
  vector&  singular_values      // вектор сингулярных значений
   );

Параметры

U

[out]  Унитарная матрица порядка m, состоящая из левых сингулярных векторов.

V

[out]  Унитарная матрица порядка n, состоящая из правых сингулярных векторов.

singular_values

[out]  Сингулярные значения

Возвращаемое значение

Возвращает true в случае успеха, иначе false.

Пример:

  matrix a= {{012345678}};
  a=a-4;
  Print("matrix a \n"a);
  a.Reshape(33);
  matrix b=a;
  Print("matrix b \n"b);
//--- сделаем SVD-разложение
  matrix UV;
  vector singular_values;
  b.SVD(UVsingular_values);
  Print("U \n"U);
  Print("V \n"V);
  Print("singular_values = "singular_values);
 
// блок проверки
//--- U * singular diagonal * 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_usvt1e-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]
  */
 }