This is in openCV, and it works with rectangular matrix as long as m>n, according to this paper
- (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;
}