2013-06-17 4 views
1

Мне нужно найти способ вычисления ортонормированного базиса для диапазона матрицы. В Matlab this function.Как вычислить ортонормированный базис квадратной (прямоугольной) матрицы

мне нужно сделать это в C/C++, и я на самом деле работаю с OpenCV

Однако, я все, что обеспечивает эту возможность в OpenCV не найден.

Я пробовал работать с cvSVD, но мои результаты неверны.

Любые подсказки?

+0

Попробуйте октаву вместо: HTTP: //www.delorie.com/gnu/docs/octave/octave_144.html – Magn3s1um

+0

Я отредактировал вопрос, если он не был достаточно явным. Я делаю это в c – dwbrito

+1

SVD не будет этого делать, но алгоритм Грэма-Шмидта будет делать, хотя я не думаю, что OpenCV имеет алгоритм. –

ответ

2

Это в OpenCV, и он работает с прямоугольной матрицей, пока т> п, согласно 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; 
} 
1

Вы хотите изучить Gnu Scientific Library, который является хорошим и хорошо протестированным библиотечным зданием поверх библиотек BLAS. Он реализует множество различных матричных операций, и обычно я начинаю использовать материал линейной алгебры. Возможно, вам понравится один из these?

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. http://www.cplusplus.com/forum/general/88888/
  2. http://www.mia.uni-saarland.de/Teaching/NAVC-SS11/sol_c8.pdf
  3. http://en.wikipedia.org/wiki/Pivot_element
  4. http://math.fullerton.edu/mathews/n2003/PivotingMod.html
  5. http://www.mathworks.com/support/solutions/en/data/1-FA9A48/index.html?solution=1-FA9A48
+0

Я думаю, что этот пример будет легче понять, если входная матрица не была квадратной или «3» должна была использоваться как «строки» и «кол» – dwbrito

+0

Правда, но я уже признал, что это чужой код в Ссылки. Кроме того, довольно легко изменить код для размещения разных размеров матрицы. Наконец, был представлен общий алгоритм, который является основной частью работы. – DevNull

+0

уверен, я это понял. Тем не менее, мне нужна версия, которая работает с любой матрицей; все еще пытаясь его реализовать. – dwbrito

0

Matlab может генерировать коды. Почему бы вам не попробовать? ??? Сначала сгенерируйте затем изучить и, наконец, использовать его, то есть все

Смежные вопросы