Я пытаюсь написать код, используя библиотеки lapacke, чтобы инвертировать сложную матрицу в C. Однако я застрял с ошибкой сегментации, которая, похоже, зависит от размера N матрицы. Более того, размер, при котором возникает ошибка сегментации, меняется каждый раз, когда я компилирую программу или прикасаюсь к чему-либо. Это заставляет меня думать, что где-то код пытается получить доступ к плохо выделенной или запрещенной памяти. К сожалению, я не понимаю, как это происходит, так как похоже, что это связано с самими функциями LAPACKE. Фактически, когда функция /*MatrixComplexInv(invA,A,N);*/ (в которой функции LAPACKE вызываются для инверсии) комментируется, возникает ошибка сегментации не.
Ниже приведен код работающий, который можно скомпилировать и запустить самостоятельно.
#include <stdio.h>
#include <lapacke.h>
#include <complex.h>
#include <stdlib.h>
#include <math.h>
void Ctranspose( double complex *, double complex * ,int );
void MatrixComplexInv(double complex *, double complex *, int );
int main(int argc, const char * * argv) {
int i,j,k,N = 4;/*if N> bigger than a small number 4,6,7.. it gives segmentation fault*/
double complex *A = calloc(N*N,sizeof(double complex)),
*b = calloc(N*N,sizeof(double complex)),
*Ap =calloc(N*N,sizeof(double complex));
double complex *invA =calloc(N*N,sizeof(double complex));
for(i=0;i<N;i++){
for(j=0;j<N;j++){
A[i*N+j] = 1+sin(i*j)*i+I*j;
Ap[i*N+j] = 1+sin(i*j)*i+I*j;
}
}
/*Segmentation fault in this function, due to
*
LAPACKE_zgetrf(LAPACK_ROW_MAJOR, n, n, tempA , n,&n);
LAPACKE_zgetri(LAPACK_ROW_MAJOR, n, tempA , n, &n );
*
* both.
*/
MatrixComplexInv(invA,A,N);
for(i=0;i<N;i++){
for(j=0;j<N;j++){
for(k = 0;k<N;k++){
b[i*N+j]+=invA[i*N + k]*Ap[k*N + j];
}
printf("(%lf,%lf)\t", creal(b[i*N + j]),cimag(b[i*N + j]));/*tests that the result produces the inverse matrix A^{-1}A = 1*/
}
printf("\n");
}
return 0;
}
void Ctranspose( double complex *Transposed, double complex *M ,int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++) Transposed[i+n*j] = M[i*n+j];
}
void MatrixComplexInv(double complex *invA, double complex *A, int n)
{
double complex *tempA = (double complex*) malloc( n*n*sizeof(double complex) );
Ctranspose(tempA,A,n);
/*SEGMENTATION HAPPEN IN THESE TWO FUNCTIONS*/
LAPACKE_zgetrf(LAPACK_ROW_MAJOR, n, n, tempA , n,&n);
LAPACKE_zgetri(LAPACK_ROW_MAJOR, n, tempA , n, &n );
Ctranspose(invA,tempA,n);
free(tempA);
}
да, это была программа для быстрого тестирования, и printf был неаккуратным. Однако ошибка сегментации остается независимой.
Почему вы выделяете память с помощью malloc, а освобождаете с помощью LAPACKE_free?
Где именно происходит segfault? Что такое трассировка стека?
Я отредактировал вопрос. Ошибка сегментации возникает в обеих функциях lapacke. Сообщение об ошибке на терминале - это просто Ошибка сегментации (дамп ядра)
А трассировка стека?
./test() [0x400ae5] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0) [0x7f94dbe9e830] ./test() [0x400949] Ошибка сегментации (дамп ядра)
ты это имеешь ввиду?





В LAPACKE_zgetrf(LAPACK_ROW_MAJOR, n, n, tempA , n,&n); последний аргумент LAPACKE_zgetrf указывает на n, одно целое число. Напротив, аргумент ipiv должен быть указатель на массив целых чисел размерности max(m,n) для хранения сводных индексов. Это может объяснить ошибку сегментации.
ipiv, вычисленный LAPACKE_zgetrf(), также должен быть предоставлен LAPACKE_zgetri() в качестве входных данных, чтобы получить правильную обратную матрицу.
Хотел бы я заплатить тебе пивом.
Спасибо за исправление, но на результат это не влияет.