Search code examples
c++copencvmatrixorthogonal

How to compute the orthonormal basis of a non square (rectangular) matrix


I need to find a way of computing the orthonormal basis for range of a matrix. In matlab this function does it.

I need to do this in c/c++ and I am actually working with OpenCV

However, I haven't found anything that provides this capability in OpenCV.

I've tried working with cvSVD, but my results aren't correct.

Any clues?


Solution

  • 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;
    }