C语言中LAPACKE dgels_uu的分段错误
我想用C中的LAPACK's dgels解决最小二乘问题| Ax-b |->min,但我得到了一个分段错误(我知道有,但代码完全不同,答案不适用于我的问题)。 我已经找到了问题所在,执行dgels_uu时它是正确的 代码:C语言中LAPACKE dgels_uu的分段错误,c,segmentation-fault,lapack,C,Segmentation Fault,Lapack,我想用C中的LAPACK's dgels解决最小二乘问题| Ax-b |->min,但我得到了一个分段错误(我知道有,但代码完全不同,答案不适用于我的问题)。 我已经找到了问题所在,执行dgels_uu时它是正确的 代码: 然后我尝试查找一个示例程序,发现(使用sgesv,但我认为它可能与DGEL类似)。在将dgels_uUa(transa,m,n,nrhs,A,lda,b,ldb,work,0,info)重写为dgels_Ua(&transa,&m,&n,&nrhs,A,&lda,b,&ldb
然后我尝试查找一个示例程序,发现(使用sgesv,但我认为它可能与DGEL类似)。在将dgels_uUa(transa,m,n,nrhs,A,lda,b,ldb,work,0,info)重写为dgels_Ua(&transa,&m,&n,&nrhs,A,&lda,b,&ldb,work,0,&info)之后,没有更多的错误消息,因此我认为这是正确的方法。
0
对于参数lwork
来说不是合法的值。实际上,它必须是指向c中整数的指针,因为在fortran中所有参数都是通过引用调用的,而在c中所有参数都是通过值调用的。此外,lwork
的值指定数组work
的长度,该数组:lwork>=max(1,MN+max(MN,NRHS))
。唯一的例外是lwork=-1
:在这种特殊情况下,函数返回到work[0]
中数组work
的最佳大小
例如,可以尝试以下行:
lapack_int lwork=n;
if (m<n){lwork=m;}
lwork=-1;
double query;
dgels_(&transa, &m, &n, &nrhs, A, &lda, b, &ldb, &query, &lwork, &info);
lwork=(int)query;
printf("the optimal size is %d \n",lwork);
work=malloc(lwork*sizeof(double));
if(work==NULL){fprintf(stderr,"maloc failed\n");exit(1);}
dgels_(&transa, &m, &n, &nrhs, A, &lda, b, &ldb, work, &lwork, &info);
printf("test 2 \n");
printf("%g %g %g\n",b[0],b[1],b[2]);
请参阅中的文档,然后向下滚动至DGEL。看起来你用很多指针来调用它,这些指针的值就足够了。另外,打开编译器的警告,这样如果你用错误类型的参数调用它,它就会抱怨。至于样式:预处理器宏通常是大写的,这样你就不会把它们和宏混淆了。因此,对于
#定义列3
而不是使用#定义列3
使用调试器,并在segfault发生后检查dgels
的参数值。@PaulOgilvie:是的,警告已打开,但gcc没有告诉我任何警告。事实上,我以前试着用值来编译它,也就是说,使用dgels(transa,m,n,nrhs,A,lda,b,ldb,work,0,info)。然而,随后我收到了很多错误消息(见编辑后的原始帖子)。@PaulOgilvie:我尝试了LAPACK_dgels(LAPACK_COL_MAJOR,transa,m,n,nrhs,A,lda,b,ldb),而不是您链接的文档中显示的dgels(LAPACK_COL_MAJOR,transa,m,n,nrhs,A,lda,b,ldb)。它编译时没有警告,也没有分段错误。但是,它仍然不能正常工作,这是一个不同的问题。非常感谢您的详细解释和正确的代码,它解决了我最初使用dgels_uu的问题和我使用LAPACK_dgel的问题。
lapack_error.c: In function ‘main’:
lapack_error.c:32:13: warning: passing argument 1 of ‘dgels_’ makes pointer from integer without a cast [-Wint-conversion]
dgels_(transa, m, n, nrhs, A, lda, b, ldb, work, 0, info);
^~~~~~
In file included from /usr/include/lapacke.h:143:0,
from lapack_error.c:2:
/usr/include/lapacke.h:14793:6: note: expected ‘char *’ but argument is of type ‘char’
void LAPACK_dgels( char* trans, lapack_int* m, lapack_int* n, lapack_int* nrhs,
^
lapack_error.c:32:21: warning: passing argument 2 of ‘dgels_’ makes pointer from integer without a cast [-Wint-conversion]
dgels_(transa, m, n, nrhs, A, lda, b, ldb, work, 0, info);
^
In file included from /usr/include/lapacke.h:143:0,
from lapack_error.c:2:
/usr/include/lapacke.h:14793:6: note: expected ‘int *’ but argument is of type ‘int’
void LAPACK_dgels( char* trans, lapack_int* m, lapack_int* n, lapack_int* nrhs,
^
lapack_error.c:32:24: warning: passing argument 3 of ‘dgels_’ makes pointer from integer without a cast [-Wint-conversion]
dgels_(transa, m, n, nrhs, A, lda, b, ldb, work, 0, info);
^
In file included from /usr/include/lapacke.h:143:0,
from lapack_error.c:2:
/usr/include/lapacke.h:14793:6: note: expected ‘int *’ but argument is of type ‘int’
void LAPACK_dgels( char* trans, lapack_int* m, lapack_int* n, lapack_int* nrhs,
^
lapack_error.c:32:27: warning: passing argument 4 of ‘dgels_’ makes pointer from integer without a cast [-Wint-conversion]
dgels_(transa, m, n, nrhs, A, lda, b, ldb, work, 0, info);
^~~~
In file included from /usr/include/lapacke.h:143:0,
from lapack_error.c:2:
/usr/include/lapacke.h:14793:6: note: expected ‘int *’ but argument is of type ‘int’
void LAPACK_dgels( char* trans, lapack_int* m, lapack_int* n, lapack_int* nrhs,
^
lapack_error.c:32:36: warning: passing argument 6 of ‘dgels_’ makes pointer from integer without a cast [-Wint-conversion]
dgels_(transa, m, n, nrhs, A, lda, b, ldb, work, 0, info);
^~~
In file included from /usr/include/lapacke.h:143:0,
from lapack_error.c:2:
/usr/include/lapacke.h:14793:6: note: expected ‘int *’ but argument is of type ‘int’
void LAPACK_dgels( char* trans, lapack_int* m, lapack_int* n, lapack_int* nrhs,
^
lapack_error.c:32:44: warning: passing argument 8 of ‘dgels_’ makes pointer from integer without a cast [-Wint-conversion]
dgels_(transa, m, n, nrhs, A, lda, b, ldb, work, 0, info);
^~~
In file included from /usr/include/lapacke.h:143:0,
from lapack_error.c:2:
/usr/include/lapacke.h:14793:6: note: expected ‘int *’ but argument is of type ‘int’
void LAPACK_dgels( char* trans, lapack_int* m, lapack_int* n, lapack_int* nrhs,
^
lapack_error.c:32:58: warning: passing argument 11 of ‘dgels_’ makes pointer from integer without a cast [-Wint-conversion]
dgels_(transa, m, n, nrhs, A, lda, b, ldb, work, 0, info);
^~~~
In file included from /usr/include/lapacke.h:143:0,
from lapack_error.c:2:
/usr/include/lapacke.h:14793:6: note: expected ‘int *’ but argument is of type ‘int’
void LAPACK_dgels( char* trans, lapack_int* m, lapack_int* n, lapack_int* nrhs,
lapack_int lwork=n;
if (m<n){lwork=m;}
lwork=-1;
double query;
dgels_(&transa, &m, &n, &nrhs, A, &lda, b, &ldb, &query, &lwork, &info);
lwork=(int)query;
printf("the optimal size is %d \n",lwork);
work=malloc(lwork*sizeof(double));
if(work==NULL){fprintf(stderr,"maloc failed\n");exit(1);}
dgels_(&transa, &m, &n, &nrhs, A, &lda, b, &ldb, work, &lwork, &info);
printf("test 2 \n");
printf("%g %g %g\n",b[0],b[1],b[2]);
#include <stdio.h>
#include <lapacke.h>
#define COL 3
#define ROW 4
int main()
{
char transa ='N';
lapack_int m, n, nrhs, lda, ldb, info;
m=ROW;
n=COL;
nrhs=1;
lda=ROW;
ldb=ROW;
double* work;
double A [COL*ROW] =
{ 1.1, 4.2, 1.7, 2.5,
2.1, 2.8, 3.4, 4.2,
8.5, 4.4, 5.2, 7.8 };
double b[ROW] =
{ 39.3,
27.4,
29.3,
42.1 };
printf("test 1 \n");
lapack_int lwork=n;
if (m<n){lwork=m;}
lwork=-1;
double query;
dgels_(&transa, &m, &n, &nrhs, A, &lda, b, &ldb, &query, &lwork, &info);
lwork=(int)query;
printf("the optimal size is %d \n",lwork);
work=malloc(lwork*sizeof(double));
if(work==NULL){fprintf(stderr,"maloc failed\n");exit(1);}
dgels_(&transa, &m, &n, &nrhs, A, &lda, b, &ldb, work, &lwork, &info);
printf("test 2 \n");
printf("%g %g %g\n",b[0],b[1],b[2]);
free(work);
double Aa [COL*ROW] =
{ 1.1, 4.2, 1.7, 2.5,
2.1, 2.8, 3.4, 4.2,
8.5, 4.4, 5.2, 7.8 };
double bb[ROW] =
{ 39.3,
27.4,
29.3,
42.1 };
//with lapacke
info= LAPACKE_dgels(LAPACK_COL_MAJOR,transa, m, n, nrhs, Aa, lda, bb, ldb);
printf("%g %g %g\n",bb[0],bb[1],bb[2]);
//
double Aaa [COL*ROW] =
{ 1.1, 4.2, 1.7,
2.5, 2.1, 2.8,
3.4, 4.2, 8.5,
4.4, 5.2, 7.8 };
double bbb[ROW] =
{ 16.3,
17.9,
45.8,
46 };
//with lapacke
info= LAPACKE_dgels(LAPACK_COL_MAJOR,'T', n, m, nrhs, Aaa, n, bbb, ldb);
printf("%g %g %g\n",bbb[0],bbb[1],bbb[2]);
double Aaaa [COL*ROW] =
{ 1.1, 4.2, 1.7,
2.5, 2.1, 2.8,
3.4, 4.2, 8.5,
4.4, 5.2, 7.8 };
double bbbb[ROW] =
{ 16.3,
17.9,
45.8,
46 };
// it is still possible to allocate the buffer yourself once for all if LAPACKE_dgels_work is used.
// it can be useful if dgels is used many times, using the same transa, m,n,nrhs,lda,ldb but different A or b.
info= LAPACKE_dgels_work(LAPACK_COL_MAJOR,'T', n, m, nrhs, Aaaa, n, bbbb, ldb,&query,-1);
lwork=(int)query;
printf("the optimal size is %d \n",lwork);
work=malloc(lwork*sizeof(double));
if(work==NULL){fprintf(stderr,"maloc failed\n");exit(1);}
info= LAPACKE_dgels_work(LAPACK_COL_MAJOR,'T', n, m, nrhs, Aaaa, n, bbbb, ldb,work,lwork);
free(work);
printf("%g %g %g\n",bbbb[0],bbbb[1],bbbb[2]);
return 0;
}