LAPACK SVD (разложение по единственному значению) - PullRequest
6 голосов
/ 19 февраля 2011

Знаешь ли ты какой-нибудь пример использования LAPACK для расчета SVD?

1 Ответ

10 голосов
/ 19 февраля 2011

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

Пример, использующий привязки C LAPACK (обратите внимание, что я написал это только сейчас, и фактически не проверял это. Также обратите внимание, что точные типы аргументов для clapack несколько различаются междуплатформы, поэтому вам может потребоваться изменить int на что-то другое):

#include <clapack.h>

void SingularValueDecomposition(int m,     // number of rows in matrix
                                int n,     // number of columns in matrix
                                int lda,   // leading dimension of matrix
                                double *a) // pointer to top-left corner
{
    // Setup a buffer to hold the singular values:
    int numberOfSingularValues = m < n ? m : n;
    double *s = malloc(numberOfSingularValues * sizeof s[0]);

    // Setup buffers to hold the matrices U and Vt:
    double *u = malloc(m*m * sizeof u[0]);
    double *vt = malloc(n*n * sizeof vt[0]);

    // Workspace and status variables:
    double workSize;
    double *work = &workSize;
    int lwork = -1;
    int *iwork = malloc(8 * numberOfSingularValues * sizeof iwork[0]);
    int info = 0;

    // Call dgesdd_ with lwork = -1 to query optimal workspace size:
    dgesdd_("A", &m, &n, a, &lda, s, u, &m, vt, &n, work, &lwork, iwork, &info);
    if (info) // handle error conditions here

    // Optimal workspace size is returned in work[0].
    lwork = workSize;
    work = malloc(lwork * sizeof work[0]);

    // Call dgesdd_ to do the actual computation:
    dgesdd_("A", &m, &n, a, &lda, s, u, &m, vt, &n, work, &lwork, iwork, &info);
    if (info) // handle error conditions here

    // Cleanup workspace:
    free(work);
    free(iwork);

    // do something useful with U, S, Vt ...

    // and then clean them up too:
    free(s);
    free(u);
    free(vt);
}
...