Как выполнить обратную операцию с матрицей, используя ускоренную структуру?

Я хотел бы найти обратную матрицу.

Я знаю, что это включает сначала факторизацию LU, а затем шаг инверсии, но я не могу найти нужную функцию, выполнив поиск в документах Apple 10.7!

Это похоже на полезный пост Инверсия симметричной матрицы в C с использованием CBLAS/LAPACK, указав, что следует использовать функции sgetrf_ и sgetri_. Однако при поиске этих терминов я ничего не нахожу в документах Xcode.

У кого-нибудь есть шаблонный код для этой матричной операции?


person Daniel Farrell    schedule 01.07.2012    source источник


Ответы (1)


Apple вообще не документирует код LAPACK, я думаю, потому что они просто реализуют стандартный интерфейс с netlib.org. Жаль, что вы не можете искать эти имена функций из встроенных документов Xcode, однако решение довольно простое: просто укажите имя функции в URL-адресе, например. для dgetrf_() перейдите по адресу http://www.netlib.org/clapack/what/double/dgetrf.c.

Чтобы инвертировать матрицу, необходимы две функции LAPACK: dgetrf_(), которая выполняет факторизацию LU, и dgetri_(), которая берет выходные данные предыдущей функции и выполняет реальную инверсию.

Я создал стандартный проект приложения с помощью Xcode, добавил Accelerate Framework, создал два файла C: matinv.h, matinv.c и отредактировал файл main.m, чтобы удалить вещи Cocoa:

// main.m

#import "matinv.h"

int main(int argc, char *argv[])
{
    int N = 3;
    double A[N*N];
    A[0] = 1; A[1] = 1; A[2] = 7;
    A[3] = 1; A[4] = 2; A[5] = 1;
    A[6] = 1; A[7] = 1; A[8] = 3;
    matrix_invert(N, A);
    //        [ -1.25  -1.0  3.25 ]
    // A^-1 = [  0.5       1.0  -1.5  ]
    //        [  0.25   0.0 -0.25 ] 
    return 0;
}

Теперь заголовочный файл,

//  matinv.h

int matrix_invert(int N, double *matrix);

а затем исходный файл,

int matrix_invert(int N, double *matrix) {

    int error=0;
    int *pivot = malloc(N*sizeof(int)); // LAPACK requires MIN(M,N), here M==N, so N will do fine.
    double *workspace = malloc(N*sizeof(double));

    /*  LU factorisation */
    dgetrf_(&N, &N, matrix, &N, pivot, &error);

    if (error != 0) {
        NSLog(@"Error 1");
        free(pivot);
        free(workspace);
        return error;
    }

    /*  matrix inversion */
    dgetri_(&N, matrix, &N, pivot, workspace, &N, &error);

    if (error != 0) {
        NSLog(@"Error 2");
        free(pivot);
        free(workspace);
        return error;
    }

    free(pivot);
    free(workspace);
    return error;
}
person Daniel Farrell    schedule 04.07.2012
comment
Каноническим справочником LAPACK является Руководство пользователя LAPACK. (netlib.org/lapack/lug) - person Stephen Canon; 04.07.2012
comment
У меня возникли проблемы со сканированием этой загадочной (мягко говоря) библиотеки LAPACK. Как я могу адаптировать этот код для одинарной точности с плавающей запятой? - person Nicolas Miari; 12.06.2013
comment
О, я нашел это: sgetrf_ и sgetri_ (S для одинарной точности?) - person Nicolas Miari; 12.06.2013
comment
Спасибо за ваш код, он мне помог. В вашем matrix_invert есть ошибка, если есть ошибка, вы пропустили выпуск пивота и рабочей области и вернулись раньше. - person X.Y.; 21.06.2013
comment
Я думаю, что размер сводной точки должен быть N*sizeof(int) от размера документов (мин (M, N)) - person combinatorial; 12.09.2014
comment
Правда, я выделяю много места для поворота! Фиксированный. - person Daniel Farrell; 13.09.2014