我需要找到一种计算矩阵范围的标准正交基的方法。在matlab中this function做到了。
我需要在c / c ++中执行此操作,而我实际上正在使用OpenCV
但是,我没有在OpenCV中找到任何提供此功能的内容。
我尝试过使用cvSVD,但结果不正确。
任何线索?
答案 0 :(得分:5)
如果您需要现有的工具包/库来处理这个问题,上面的@PureW提供了一个有效的答案。如果您需要自己实现此功能,那么您正在寻找Gram-Schmidt算法的实现。
以下是帮助您验证代码的示例问题:
http://www.mia.uni-saarland.de/Teaching/NAVC-SS11/sol_c8.pdf
以下是代码(请参阅完整学分的参考资料)。请注意:此示例假定您有一组正确缩放的数据。如果您的矩阵规模较小,则可能需要考虑LU分解或适当的枢轴策略。参考文献中也有关于此主题的有用链接。
#include <cstdlib>
#include <iostream>
#include <math.h>
using namespace std;
// example: http://www.mia.uni-saarland.de/Teaching/NAVC-SS11/sol_c8.pdf
// page 5
double a[3][3] = {
{1.0, 2.0, 1.0},
{0.0, 1.0, 2.0},
{1.0, 2.0, 0.0}
};
// any column of a is a vector
double r[3][3], q[3][3];
int main(int argc, char *argv[]) {
int k, i, j;
for (k=0; k<3; k++){
r[k][k]=0; // equivalent to sum = 0
for (i=0; i<3; i++)
r[k][k] = r[k][k] + a[i][k] * a[i][k]; // rkk = sqr(a0k) + sqr(a1k) + sqr(a2k)
r[k][k] = sqrt(r[k][k]); // ||a||
cout << endl << "R"<<k<<k<<": " << r[k][k];
for (i=0; i<3; i++) {
q[i][k] = a[i][k]/r[k][k];
cout << " q"<<i<<k<<": "<<q[i][k] << " ";
}
for(j=k+1; j<3; j++) {
r[k][j]=0;
for(i=0; i<3; i++) r[k][j] += q[i][k] * a[i][j];
cout << endl << "r"<<k<<j<<": " <<r[k][j] <<endl;
for (i=0; i<3; i++) a[i][j] = a[i][j] - r[k][j]*q[i][k];
for (i=0; i<3; i++) cout << "a"<<j<<": " << a[i][j]<< " ";
}
}
system("PAUSE");
return EXIT_SUCCESS;
}
<强>参考文献:强>
答案 1 :(得分:2)
这是在openCV中,根据this paper
,只要m> n,就可以使用矩形矩阵- (CvMat *) buildOrthonormal:(CvMat *) matrix {
NSInteger rows = matrix->rows;
NSInteger cols = matrix->cols;
CvMat *Q = cvCreateMat(rows, cols, kMatrixType);
CvMat *R = cvCreateMat(cols, cols, kMatrixType);
for (NSInteger k = 0; k < cols; k++) {
cvSetReal2D(R, k, k, 0.0f);
for (NSInteger i = 0; i < rows; i++) {
double value = cvGetReal2D(R, k, k) + cvGetReal2D(matrix, i, k) * cvGetReal2D(matrix, i, k);
cvSetReal2D(R, k, k, value);
}
cvSetReal2D(R, k, k, sqrt(cvGetReal2D(R, k, k)));
for (NSInteger i = 0; i < rows; i++) {
double value = cvGetReal2D(matrix, i, k) / cvGetReal2D(R, k, k);
cvSetReal2D(Q, i, k, value);
}
for (NSInteger j = k + 1; j < cols; j++) {
cvSetReal2D(R, k, j, 0.0f);
for (NSInteger i = 0; i < rows; i++) {
double value = cvGetReal2D(R, k, j) + cvGetReal2D(Q, i, k) * cvGetReal2D(matrix, i, j);
cvSetReal2D(R, k, j, value);
}
for (NSInteger i = 0; i < rows; i++) {
double value = cvGetReal2D(matrix, i, j) - cvGetReal2D(R, k, j) * cvGetReal2D(Q, i, k);
cvSetReal2D(matrix, i, j, value);
}
}
}
cvReleaseMat(&R);
return Q;
}
答案 2 :(得分:1)
您想要查看Gnu Scientific Library,这是一个在BLAS库之上构建的经过良好测试的优秀库。它实现了许多不同的矩阵运算,通常我会从线性代数的东西开始。也许these中有一个适合你?
答案 3 :(得分:0)
Matlab可以生成代码。你为什么不试试呢??? 首先生成然后检查并最终使用它,这就是全部