特異値分解のサンプルソースコードをいくつか紹介します.といっても,特異値分解そのものはライブラリの関数を呼び出すだけです.MATLABによるSVDの実装,PythonとnumpyによるSVDの実装などを載せています.また,C/C++のプログラムも載せています.C/C++は,Eigenライブラリによる特異値分解のソースコード,OpenCVによる特異値分解のソースコードなどを載せています.
ROW = randi([2 10]);
COL = randi([2 10]);
A = 99.9*rand(ROW, COL);
[U,W,V] = svd(A,'econ');
VT = V.';
disp("SVD result")
disp("A =")
disp(A)
disp("U =")
disp(U)
disp("W =")
disp(W)
disp("V^T =")
disp(VT)
check = U * W * VT;
disp("Check")
disp("U W V^T =")
disp(check)
disp("Coincide with A")
import numpy as
np
def main():
ROW = np.random.randint(2,
10)
COL = np.random.randint(2,
10)
A = np.random.uniform(0.0,
99.9, (ROW, COL))
U,W,VT = np.linalg.svd(A, full_matrices=False)
print("SVD result")
print("A=", A)
print("U=", U)
print("W=", W)
print("V^T=",
VT)
matw = np.diag(W)
check = np.dot(np.dot(U, matw), VT)
print("Check")
print("U W V^T=",
check)
print("Coincide with
A")
if __name__ ==
'__main__':
main()
import numpy as
np
import cv2
def main():
ROW = np.random.randint(2,
10)
COL = np.random.randint(2,
10)
A = np.random.uniform(0.0,
99.9, (ROW, COL))
W,U,VT = cv2.SVDecomp(A)
print("SVD
result")
print("A=",
A)
print("U=",
U)
print("W=",
W)
print("V^T=",
VT)
matw = np.diagflat(W)
check = np.dot(np.dot(U, matw), VT)
print("Check")
print("U
W V^T=", check)
print("Coincide
with A")
if __name__ ==
'__main__':
main()
#include <stdlib.h>
#include <time.h>
#include <iostream>
using namespace std;
#include "Eigen/Core"
#include "Eigen/SVD"
using namespace Eigen;
int main()
{
srand((unsigned)time(NULL));
int ROW = rand() % 8 + 2;
int COL = rand() % 8 + 2;
MatrixXd A = (MatrixXd::Random(ROW,
COL) + MatrixXd::Ones(ROW,
COL)) / 2.0 *
99.9;
JacobiSVD<MatrixXd>
svd(A, ComputeThinU |
ComputeThinV);
MatrixXd VT =
svd.matrixV().transpose();
cout <<
"SVD result" <<
endl << endl;
cout <<
"A=" << endl
<< A << endl
<< endl;
cout <<
"U=" << endl
<< svd.matrixU() <<
endl << endl;
cout <<
"W=" << endl
<< svd.singularValues()
<< endl <<
endl;
cout <<
"V^T=" << endl
<< VT << endl
<< endl;
cout << endl;
MatrixXd W =
svd.singularValues().asDiagonal();
MatrixXd check =
svd.matrixU() * W *
VT;
cout <<
"Check" <<
endl << endl;
cout <<
"U W V^T=" <<
endl << kenzan <<
endl << endl;
cout <<
"Coincide with A" <<
endl << endl;
cout <<
"Push enter" <<
endl;
cin.get();
return 0;
}
#include <stdlib.h>
#include <time.h>
#include <iostream>
using namespace std;
#include "Eigen/Core"
#include "Eigen/SVD"
using namespace Eigen;
int main()
{
srand((unsigned)time(NULL));
int ROW = rand() % 8 + 2;
int COL = rand() % 8 + 2;
MatrixXd A = (MatrixXd::Random(ROW,
COL) + MatrixXd::Ones(ROW,
COL)) / 2.0 *
99.9;
BDCSVD<MatrixXd>
svd(A, ComputeThinU |
ComputeThinV);
MatrixXd VT =
svd.matrixV().transpose();
cout <<
"SVD result" <<
endl << endl;
cout <<
"A=" << endl
<< A << endl
<< endl;
cout <<
"U=" << endl
<< svd.matrixU() <<
endl << endl;
cout <<
"W=" << endl
<< svd.singularValues()
<< endl <<
endl;
cout <<
"V^T=" << endl
<< VT << endl
<< endl;
cout << endl;
MatrixXd W =
svd.singularValues().asDiagonal();
MatrixXd check =
svd.matrixU() * W *
VT;
cout <<
"Check" <<
endl << endl;
cout <<
"U W V^T=" <<
endl << kenzan <<
endl << endl;
cout <<
"Coincide with A" <<
endl << endl;
cout <<
"Push enter" <<
endl;
cin.get();
return 0;
}
// Include directory C:\OpenCV3.1\build\include
// Library directory (x64)
C:\OpenCV3.1\build\x64\vc14\lib
// PATH (x64) C:\OpenCV3.1\build\x64\vc14\bin
#if _DEBUG
#pragma comment(lib,
"opencv_world310d.lib")
#else
#pragma comment(lib,
"opencv_world310.lib")
#endif
#include <time.h>
#include <iostream>
using namespace std;
#include
<opencv2/opencv.hpp>
using namespace cv;
int main()
{
RNG gen(getTickCount());
int ROW = gen.uniform(2,
10);
int COL = gen.uniform(2,
10);
Mat A(ROW, COL,
CV_64F);
gen.fill(A, RNG::UNIFORM,
0.0, 99.9);
SVD svd(A);
cout <<
"SVD result" <<
endl << endl;
cout <<
"A=" << A
<< endl <<
endl;
cout <<
"U=" << svd.u
<< endl <<
endl;
cout <<
"W=" << svd.w
<< endl <<
endl;
cout <<
"V^T=" <<
svd.vt << endl <<
endl;
cout << endl;
Mat matw =
Mat::diag(svd.w);
Mat check = svd.u
* matw *
svd.vt;
cout <<
"Check" <<
endl << endl;
cout <<
"U W V^T=" <<
check << endl <<
endl;
cout <<
"Coincide with A" <<
endl << endl;
cout <<
"Push enter" <<
endl;
cin.get();
return 0;
}
// Include directory C:\OpenCV2.4.11\build\include
// Library directory (x86)
C:\OpenCV2.4.11\build\x86\vc12\lib
// Library directory (x64)
C:\OpenCV2.4.11\build\x64\vc12\lib
// PATH (x86) C:\OpenCV2.4.11\build\x86\vc12\bin
// PATH (x64) C:\OpenCV2.4.11\build\x64\vc12\bin
#if _DEBUG
#pragma comment(lib,
"opencv_core2411d.lib")
#pragma comment(lib,
"opencv_highgui2411d.lib")
#pragma comment(lib,
"opencv_imgproc2411d.lib")
#else
#pragma comment(lib,
"opencv_core2411.lib")
#pragma comment(lib,
"opencv_highgui2411.lib")
#pragma comment(lib,
"opencv_imgproc2411.lib")
#endif
#include
<opencv2/opencv.hpp>
using namespace cv;
#include <stdio.h>
#include <conio.h>
#include <time.h>
int main()
{
srand((unsigned)time(NULL));
int ROW = rand() % 8 + 2;
int COL = rand() % 8 + 2;
Mat A(ROW, COL,
CV_64F);
for (int
i = 0; i < A.rows; i++) {
for
(int j = 0; j < A.cols; j++) {
A.at<double>(i,
j) = 99.9 * (double)rand() / (double)RAND_MAX;
}
}
SVD svd(A);
printf("SVD
result\n");
printf("\n");
printf("A=\n");
for (int
i = 0; i < A.rows; i++) {
for
(int j = 0; j < A.cols; j++) {
printf("%1.2f ",
A.at<double>(i, j));
}
printf("\n");
}
printf("U=\n");
for (int
i = 0; i < svd.u.rows; i++) {
for
(int j = 0; j < svd.u.cols; j++) {
printf("%1.2f ",
svd.u.at<double>(i, j));
}
printf("\n");
}
printf("W=\n");
for (int
i = 0; i < svd.w.rows; i++) {
for
(int j = 0; j < svd.w.cols; j++) {
printf("%1.2f ",
svd.w.at<double>(i, j));
}
printf("\n");
}
printf("V^T=\n");
for (int
i = 0; i < svd.vt.rows; i++) {
for
(int j = 0; j < svd.vt.cols; j++) {
printf("%1.2f ",
svd.vt.at<double>(i, j));
}
printf("\n");
}
printf("\n");
Mat matw =
Mat::zeros(svd.w.rows, svd.w.rows,
CV_64F);
for (int
i = 0; i < svd.w.rows; i++) {
matw.at<double>(i,
i) = svd.w.at<double>(i, 0);
}
Mat check = svd.u
* matw *
svd.vt;
printf("Check\n");
printf("U
W V^T=\n");
for (int
i = 0; i < check.rows; i++) {
for
(int j = 0; j < check.cols; j++) {
printf("%1.2f ",
check.at<double>(i, j));
}
printf("\n");
}
printf("Coincide
with A\n");
_getch();
return 0;
}
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include "nr3/nr3.h"
#include "nr3/svd.h"
int main()
{
srand((unsigned)time(NULL));
int ROW = rand() % 8 + 2;
int COL = rand() % 8 + 2;
MatDoub A(ROW, COL);
for (int
i = 0; i < ROW; i++) {
for
(int j = 0;j < COL;j++) {
A[i][j]
= 99.9 * (double)rand() / (double)RAND_MAX;
}
}
SVD svd(A);
printf("SVD
result\n");
printf("\n");
printf("A=\n");
for (int
i = 0; i < ROW; i++) {
for
(int j = 0; j < COL; j++) {
printf("%1.2f ",
A[i][j]);
}
printf("\n");
}
printf("U=\n");
for (int
i = 0; i < svd.u.nrows(); i++) {
for
(int j = 0; j < svd.u.ncols(); j++) {
printf("%1.2f ",
svd.u[i][j]);
}
printf("\n");
}
printf("W=\n");
for (int
i = 0; i < svd.w.size(); i++) {
printf("%1.2f\n",
svd.w[i]);
}
printf("V^T=\n");
for (int
i = 0; i < svd.v.ncols(); i++) {
for
(int j = 0; j < svd.v.nrows(); j++) {
printf("%1.2f ",
svd.v[j][i]);
}
printf("\n");
}
printf("\n");
MatDoub check(ROW, COL);
for (int
i = 0; i < ROW; i++) {
for
(int j = 0; j < COL; j++) {
double val = 0.0;
for (int k =
0; k < svd.u.ncols(); k++) {
val += svd.u[i][k]
* svd.w[k] *
svd.v[j][k];
}
check[i][j]
= val;
}
}
printf("Check\n");
printf("U
W V^T=\n");
for (int
i = 0; i < check.nrows(); i++) {
for
(int j = 0; j < check.ncols(); j++) {
printf("%1.2f ",
check[i][j]);
}
printf("\n");
}
printf("Coincide
with A\n");
printf("Push
any key\n");
_getch();
return 0;
}