使用L中的LAPACKE dgels_进行分段错误

时间:2017-10-15 17:04:12

标签: c segmentation-fault lapack

我想在C中用LAPACK的dgels_来解决最小二乘问题| Ax-b | - > min,但是我得到了一个分段错误错误(我知道有{{ 3}},但代码完全不同,答案不适用于我的问题)。 我已经找到了问题,dgels_执行时是正确的。

代码:

#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[COL];

 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] = 
     { 1.5,         
       2.1,         
       3.8,         
       3.4 };

 printf("test 1 \n");
 dgels_(&transa, &m, &n, &nrhs, A, &lda, b, &ldb, work, 0, &info);
 printf("test 2 \n");

 return 0;
}

第一个&#34;测试1&#34;打印然后有分段错误错误。

编辑: 我之前尝试使用值编译它,即使用dgels_(transa,m,n,nrhs,A,lda,b,ldb,work,0,info)。 但是,我收到了很多错误消息:

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,

然后我尝试查找示例程序并找到a similar problem(使用sgesv,但我认为它可能与dgels类似)。并且在将dgels_(transa,m,n,nrhs,A,lda,b,ldb,work,0,info)重写为dgels _(&amp; transa,&amp; m,&amp; n,&amp; nrhs,A,&amp; lda,b,&amp; ldb,work,0,&amp; info)没有更多错误消息,所以我认为这是正确的方法。

1 个答案:

答案 0 :(得分:1)

0不是dgels的参数lwork的合法值。实际上,它必须是指向c中整数的指针,因为所有参数都在fortran中通过引用调用,而所有参数都由c中的值调用。此外,lwork的值指定数组work的长度,must be larger than 1LWORK >= max( 1, MN + max( MN, NRHS ) )。唯一的例外是lwork=-1:在这种特殊情况下,函数会返回work中数组work[0]的最佳大小。

例如,可以尝试以下几行:

    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]);

dgels_有两次调用:第一次返回work的正确大小。然后,分配work并再次调用dgels_以执行最小二乘最小化。

结果可能与常规C开发人员所期望的结果不同:Fortran and C order of dimensions for multidimensional arrays are different .Lapacke包装器提供函数LAPACKE_dgels()LAPACKE_dgels_work()参数LAPACK_COL_MAJOR / { {1}}和LAPACK_ROW_MAJOR。始终确保通过执行测试为这些参数使用正确的值!如果失败,请尝试不同的值......

以下是基于您的示例代码,展示了通过Lapacke界面调用transa的不同方法。它可以由dgels编译。

gcc main.c -o main -llapacke -llapack -lblas -lm -Wall