C++,LAPACK:未定义对链接库的“dsyev”的引用
C++, LAPACK: undefined reference to `dsyev' with libraries linked
我正在编写一个程序,其中我需要使用 LAPACK 中的库子例程 dsyev 对矩阵进行对角化。首先,我使用测试代码来确保我正确链接了 BLAS 和 LAPACK 库。该代码是:
// LAPACK test code
//compile with: g++ -Wall -L/lib64 -llapack -lblas LAPACK_testcode.cpp -o LAPACK_testcode.x
#include <iostream>
#include <vector>
using namespace std;
extern "C" void dgetrf_(int* dim1, int* dim2, double* a, int* lda, int* ipiv, int* info);
extern "C" void dgetrs_(char *TRANS, int *N, int *NRHS, double *A, int *LDA, int *IPIV, double *B, int *LDB, int *INFO );
int main()
{
char trans = 'N';
int dim = 2;
int nrhs = 1;
int LDA = dim;
int LDB = dim;
int info;
vector<double> a, b;
a.push_back(1);
a.push_back(1);
a.push_back(1);
a.push_back(-1);
b.push_back(2);
b.push_back(0);
int ipiv[3];
dgetrf_(&dim, &dim, &*a.begin(), &LDA, ipiv, &info);
dgetrs_(&trans, &dim, &nrhs, & *a.begin(), &LDA, ipiv, & *b.begin(), &LDB, &info);
std::cout << "solution is:";
std::cout << "[" << b[0] << ", " << b[1] << ", " << "]" << std::endl;
std::cout << "Info = " << info << std::endl;
return(0);
}
此代码已编译并且 运行 没有问题,所以我不认为问题是链接库的问题。接下来 运行 来自 Intel 网站的 dsyev 示例 C 程序:
不要在此处发布代码,只需查看超链接即可。 运行 该程序(我将其保存为 C++ 程序并确保 LAPACK 函数原型具有 extern "C")产生以下错误:
dsyev_example.cpp: In function ‘int main()’:
dsyev_example.cpp:95:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev_example.cpp:95:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev_example.cpp:99:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev_example.cpp:99:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev_example.cpp:106:49: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev_example.cpp:108:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
/tmp/ccpoVl5n.o: In function `main':
dsyev_example.cpp:(.text+0x8b): undefined reference to `dsyev'
dsyev_example.cpp:(.text+0xf7): undefined reference to `dsyev'
collect2: error: ld returned 1 exit status
然后我尝试了我的程序,它有类似的错误:
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include "timer.h"
using namespace std;
const int N = 10; // Matrix is of size N x N
// ****** NEED TO LINK BLAS AND LAPACK LIBRARIES IN ORDER TO COMPILE ******
// g++ -Wall -L/lib64 -llapack -lblas matrix_multiply.cpp -o matrix_multiply.x
/* DSYEV prototype */
extern "C"
{
void dsyev( char* jobz, char* uplo, int* n, double* a, int* lda,
double* w, double* work, int* lwork, int* info );
}
/* DGEMM prototype */
extern "C"
{
void dgemm(const char *transa, const char *transb, int *l, int *n,
int *m, double *alpha, const void *a, int *lda, void *b,
int *ldb, double *beta, void *c, int *ldc);
}
/* Auxiliary routines prototypes */
extern "C"
{
void print_matrix( char* desc, int m, int n, double* a, int lda );
}
void initialize (double a [N][N]);
void print (int m, int n, double a [N][N]);
int main()
{
// declaration of matrix
double A [N][N];
// call initialize to initialize matrix here
initialize (A);
cout << "The initial matrix A is:\n";
// call print to print matrices here
print (N, N, A);
// Declaring Function Input for DSYEV
char jobz = 'V'; // 'V': Compute eigenvalues and eigenvectors.
char uplo = 'U'; // 'U': Upper triangle of A is stored.
int n = N; // The order of the matrix A, with n >= 0.
int lda = N; // The leading dimension of the array A, LDA >= max(1,N).
int lwork = N * N; // The length of the array work, lwork >= max(1,3*N-1).
int info = 1; // = 0: successful exit
double w[N]; // w = array of eigenvalues in ascending order
double work[N]; // work =
// Convert 2d array into 1d array for use in dsyev
double b [N*N];
for (int q = 0; q < n; q++)
{
for (int t = 0; t < n; t++)
{
b[q * n + t] = A[q][t];
}
}
// Print 1d array
for (int i = 0; i < N * N; i++)
{
cout << setw (8) << i << " ";
}
dsyev(&jobz, &uplo, &n, b, &lda, w, work, &lwork, &info);
/* Check for convergence with dsyev */
if( info > 0 )
{
cout << "The algorithm failed to compute eigenvalues." << endl;
exit(1);
}
/* Print eigenvalues */
print_matrix( "Eigenvalues", 1, n, w, 1 );
/* Print eigenvectors */
print_matrix( "Eigenvectors (stored columnwise)", n, n, b, lda );
/*
timespec before, after;
get_time(&before);
// O(N^3) ALGORITHM FOR TWO-INDEX SIMILARITY TRANSFORMATION
for (int j = 0; j < N; j++)
{
for (int p = 0; p < N; p++)
{
int sum = 0;
for (int q = 0; q < N; q++)
{
sum += F[p][q] * T[q][j];
}
G[p][j] = sum;
}
}
for (int j = 0; j < N; j++)
{
for (int i = 0; i < N; i++)
{
int sum = 0;
for (int p = 0; p < N; p++)
{
sum += T[p][i] * G[p][j];
}
H[i][j] = sum;
}
}
get_time(&after);
timespec time_diff;
diff(&before,&after,&time_diff);
// Time in seconds
double time_s = time_diff.tv_sec + (double)(time_diff.tv_nsec)/1.0e9;
cout << "\nThe time for the operation was " << time_s << endl;
// call print to print result here
print ();
*/
cout << "\n\n";
return 0;
}
// initialize sets all values in the matrix to desired form
void initialize (double a [N][N])
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
a [i][j] = 1.0;
a [j][i] = 1.0;
if (i < 5)
{
a [i][i] = 1.0 + (0.1 * i);
}
if (i > 5)
{
a [i][i] = 2 * (i + 1.0) - 1.0;
}
}
}
}
// prints the matrix
void print (int m, int n, double a [N][N])
{
for (int i = 0; i < m; i++)
{
cout << endl;
for (int j = 0; j < n; j++)
cout << setw (8) << a [i][j];
}
cout << endl;
}
/* Auxiliary routine: printing a matrix */
void print_matrix( char* desc, int m, int n, double* a, int lda )
{
int i, j;
printf( "\n %s\n", desc );
for( i = 0; i < m; i++ )
{
for( j = 0; j < n; j++ ) printf( " %6.2f", a[i+j*lda] );
printf( "\n" );
}
}
我又一次收到以下错误:
matrix_multiply.cpp: In function ‘int main()’:
matrix_multiply.cpp:91:45: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
matrix_multiply.cpp:93:68: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
/tmp/ccVXf4OM.o: In function `main':
matrix_multiply.cpp:(.text+0x229): undefined reference to `dsyev'
collect2: error: ld returned 1 exit status
LAPACK 和 BLAS 库都位于 /lib64(如 liblapack.so 和 libblas.so)。正在使用的命令在两个已发布程序的顶部都有注释。考虑到测试程序 运行 成功,我认为问题不在于链接库?如果有人对问题的可能原因有任何线索,我将非常感谢您的指点。谢谢!
注意外部函数声明的区别:
extern "C" void dgetrf_(int* dim1, ... ); // OK
extern "C"
{
void dsyev( ... ); // KO
}
dsyev
的声明缺少下划线 _
。这个下划线是从哪里来的?这来自将 LAPACK 源代码中的函数名称翻译为库的目标文件中的函数名称的命名约定。例如,让我们看一下 naming convention of gfortran:
By default, the procedure name is the lower-cased Fortran name with an appended underscore (_); using -fno-underscoring no underscore is appended while -fsecond-underscore appends two underscores. Depending on the target system and the calling convention, the procedure might be additionally dressed; for instance, on 32bit Windows with stdcall, an at-sign @ followed by an integer number is appended. For the changing the calling convention, see see GNU Fortran Compiler Directives.
因此,命名约定可能取决于编译器、编译器选项和操作系统。因此,如果使用给定的命名约定在 C++ 代码中声明函数,则 C++ 代码可能不可移植:在不同的计算机上或使用不同的编译器编译它可能会失败。
为了避免此类问题,存在一个名为 LAPACKE 的接口。该接口负责命名约定。最后,您需要做的就是通过 extern "C" { #include <lapacke.h>}
(在 C++ 中)包含 lapacke.h
,将 link 添加到 lapacke 并将 LAPACKE_
添加到 lapack 函数的名称之前。这是使用 dsyev()
:
的简单示例 C 代码
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
#include <time.h>
#include <lapacke.h>
int main(void){
int n=200;
srand(time(NULL));
// allocate the matrix, unpacked storage
double** A=malloc(n*sizeof(double*));
if(A==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
A[0]=malloc(n*n*sizeof(double));
if(A[0]==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
int i;
for(i=1;i<n;i++){
A[i]=&A[0][n*i];
}
//populte the matrix, only the lower diagonal part
int j;
for(i=0;i<n;i++){
for(j=0;j<i;j++){
A[i][j]=rand()/((double)RAND_MAX);
}
A[i][i]=rand()/((double)RAND_MAX)+42.;
}
//saving the matrix, because zheev() changes it.
double complex** As=malloc(n*sizeof(double complex*));
if(As==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
As[0]=malloc(n*n*sizeof(double complex));
if(As[0]==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
for(i=1;i<n;i++){
As[i]=&As[0][n*i];
}
for(i=0;i<n;i++){
for(j=0;j<i;j++){
As[i][j]=A[i][j];
}
As[i][i]=A[i][i];
}
//transpose part
for(i=0;i<n;i++){
for(j=i+1;j<n;j++){
As[i][j]=(A[j][i]);
}
}
//let's get the eigenvalues and the eigenvectors!
double* w=malloc(n*sizeof(double));
if(w==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
int lda = n;
int info = LAPACKE_dsyev(LAPACK_ROW_MAJOR, 'V', 'L', n, A[0], lda, w);
if(info<0){
fprintf(stderr,"argument %d has illegal value\n",-info);
}
if(info>0){
fprintf(stderr,"algorithm failed to converge... bad condition number ?\n");
}
//printing the eigenvalues...
for(i=0;i<n;i++){
printf("%d %g\n",i,w[i]);
}
//let's check that the column i of A is now a right eigenvectors corresponding to the eigenvalue w[i]...
int l=42;
double *res=malloc(n*sizeof(double));
if(res==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
for(i=0;i<n;i++){
res[i]=0;
for(j=0;j<n;j++){
res[i]+=As[i][j]*A[j][l];
}
res[i]-=w[l]*A[i][l];
}
double norm2res=0;
double norm2vec=0;
for(i=0;i<n;i++){
norm2res+=res[i]*res[i];
norm2vec+=A[i][l]*A[i][l];
}
printf("the norm of the eigenvector is %g\n",sqrt(norm2vec));
printf("||Ax-\lambda*x||_2/||x||_2 is about %g\n",sqrt(norm2res/norm2vec));
//free the matrix
free(A[0]);
free(A);
free(As[0]);
free(As);
free(w);
free(res);
return 0;
}
由gcc main.c -o main -llapacke -llapack -lblas -lm -Wall
编译
我正在编写一个程序,其中我需要使用 LAPACK 中的库子例程 dsyev 对矩阵进行对角化。首先,我使用测试代码来确保我正确链接了 BLAS 和 LAPACK 库。该代码是:
// LAPACK test code
//compile with: g++ -Wall -L/lib64 -llapack -lblas LAPACK_testcode.cpp -o LAPACK_testcode.x
#include <iostream>
#include <vector>
using namespace std;
extern "C" void dgetrf_(int* dim1, int* dim2, double* a, int* lda, int* ipiv, int* info);
extern "C" void dgetrs_(char *TRANS, int *N, int *NRHS, double *A, int *LDA, int *IPIV, double *B, int *LDB, int *INFO );
int main()
{
char trans = 'N';
int dim = 2;
int nrhs = 1;
int LDA = dim;
int LDB = dim;
int info;
vector<double> a, b;
a.push_back(1);
a.push_back(1);
a.push_back(1);
a.push_back(-1);
b.push_back(2);
b.push_back(0);
int ipiv[3];
dgetrf_(&dim, &dim, &*a.begin(), &LDA, ipiv, &info);
dgetrs_(&trans, &dim, &nrhs, & *a.begin(), &LDA, ipiv, & *b.begin(), &LDB, &info);
std::cout << "solution is:";
std::cout << "[" << b[0] << ", " << b[1] << ", " << "]" << std::endl;
std::cout << "Info = " << info << std::endl;
return(0);
}
此代码已编译并且 运行 没有问题,所以我不认为问题是链接库的问题。接下来 运行 来自 Intel 网站的 dsyev 示例 C 程序:
不要在此处发布代码,只需查看超链接即可。 运行 该程序(我将其保存为 C++ 程序并确保 LAPACK 函数原型具有 extern "C")产生以下错误:
dsyev_example.cpp: In function ‘int main()’:
dsyev_example.cpp:95:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev_example.cpp:95:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev_example.cpp:99:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev_example.cpp:99:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev_example.cpp:106:49: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev_example.cpp:108:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
/tmp/ccpoVl5n.o: In function `main':
dsyev_example.cpp:(.text+0x8b): undefined reference to `dsyev'
dsyev_example.cpp:(.text+0xf7): undefined reference to `dsyev'
collect2: error: ld returned 1 exit status
然后我尝试了我的程序,它有类似的错误:
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include "timer.h"
using namespace std;
const int N = 10; // Matrix is of size N x N
// ****** NEED TO LINK BLAS AND LAPACK LIBRARIES IN ORDER TO COMPILE ******
// g++ -Wall -L/lib64 -llapack -lblas matrix_multiply.cpp -o matrix_multiply.x
/* DSYEV prototype */
extern "C"
{
void dsyev( char* jobz, char* uplo, int* n, double* a, int* lda,
double* w, double* work, int* lwork, int* info );
}
/* DGEMM prototype */
extern "C"
{
void dgemm(const char *transa, const char *transb, int *l, int *n,
int *m, double *alpha, const void *a, int *lda, void *b,
int *ldb, double *beta, void *c, int *ldc);
}
/* Auxiliary routines prototypes */
extern "C"
{
void print_matrix( char* desc, int m, int n, double* a, int lda );
}
void initialize (double a [N][N]);
void print (int m, int n, double a [N][N]);
int main()
{
// declaration of matrix
double A [N][N];
// call initialize to initialize matrix here
initialize (A);
cout << "The initial matrix A is:\n";
// call print to print matrices here
print (N, N, A);
// Declaring Function Input for DSYEV
char jobz = 'V'; // 'V': Compute eigenvalues and eigenvectors.
char uplo = 'U'; // 'U': Upper triangle of A is stored.
int n = N; // The order of the matrix A, with n >= 0.
int lda = N; // The leading dimension of the array A, LDA >= max(1,N).
int lwork = N * N; // The length of the array work, lwork >= max(1,3*N-1).
int info = 1; // = 0: successful exit
double w[N]; // w = array of eigenvalues in ascending order
double work[N]; // work =
// Convert 2d array into 1d array for use in dsyev
double b [N*N];
for (int q = 0; q < n; q++)
{
for (int t = 0; t < n; t++)
{
b[q * n + t] = A[q][t];
}
}
// Print 1d array
for (int i = 0; i < N * N; i++)
{
cout << setw (8) << i << " ";
}
dsyev(&jobz, &uplo, &n, b, &lda, w, work, &lwork, &info);
/* Check for convergence with dsyev */
if( info > 0 )
{
cout << "The algorithm failed to compute eigenvalues." << endl;
exit(1);
}
/* Print eigenvalues */
print_matrix( "Eigenvalues", 1, n, w, 1 );
/* Print eigenvectors */
print_matrix( "Eigenvectors (stored columnwise)", n, n, b, lda );
/*
timespec before, after;
get_time(&before);
// O(N^3) ALGORITHM FOR TWO-INDEX SIMILARITY TRANSFORMATION
for (int j = 0; j < N; j++)
{
for (int p = 0; p < N; p++)
{
int sum = 0;
for (int q = 0; q < N; q++)
{
sum += F[p][q] * T[q][j];
}
G[p][j] = sum;
}
}
for (int j = 0; j < N; j++)
{
for (int i = 0; i < N; i++)
{
int sum = 0;
for (int p = 0; p < N; p++)
{
sum += T[p][i] * G[p][j];
}
H[i][j] = sum;
}
}
get_time(&after);
timespec time_diff;
diff(&before,&after,&time_diff);
// Time in seconds
double time_s = time_diff.tv_sec + (double)(time_diff.tv_nsec)/1.0e9;
cout << "\nThe time for the operation was " << time_s << endl;
// call print to print result here
print ();
*/
cout << "\n\n";
return 0;
}
// initialize sets all values in the matrix to desired form
void initialize (double a [N][N])
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
a [i][j] = 1.0;
a [j][i] = 1.0;
if (i < 5)
{
a [i][i] = 1.0 + (0.1 * i);
}
if (i > 5)
{
a [i][i] = 2 * (i + 1.0) - 1.0;
}
}
}
}
// prints the matrix
void print (int m, int n, double a [N][N])
{
for (int i = 0; i < m; i++)
{
cout << endl;
for (int j = 0; j < n; j++)
cout << setw (8) << a [i][j];
}
cout << endl;
}
/* Auxiliary routine: printing a matrix */
void print_matrix( char* desc, int m, int n, double* a, int lda )
{
int i, j;
printf( "\n %s\n", desc );
for( i = 0; i < m; i++ )
{
for( j = 0; j < n; j++ ) printf( " %6.2f", a[i+j*lda] );
printf( "\n" );
}
}
我又一次收到以下错误:
matrix_multiply.cpp: In function ‘int main()’:
matrix_multiply.cpp:91:45: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
matrix_multiply.cpp:93:68: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
/tmp/ccVXf4OM.o: In function `main':
matrix_multiply.cpp:(.text+0x229): undefined reference to `dsyev'
collect2: error: ld returned 1 exit status
LAPACK 和 BLAS 库都位于 /lib64(如 liblapack.so 和 libblas.so)。正在使用的命令在两个已发布程序的顶部都有注释。考虑到测试程序 运行 成功,我认为问题不在于链接库?如果有人对问题的可能原因有任何线索,我将非常感谢您的指点。谢谢!
注意外部函数声明的区别:
extern "C" void dgetrf_(int* dim1, ... ); // OK
extern "C"
{
void dsyev( ... ); // KO
}
dsyev
的声明缺少下划线 _
。这个下划线是从哪里来的?这来自将 LAPACK 源代码中的函数名称翻译为库的目标文件中的函数名称的命名约定。例如,让我们看一下 naming convention of gfortran:
By default, the procedure name is the lower-cased Fortran name with an appended underscore (_); using -fno-underscoring no underscore is appended while -fsecond-underscore appends two underscores. Depending on the target system and the calling convention, the procedure might be additionally dressed; for instance, on 32bit Windows with stdcall, an at-sign @ followed by an integer number is appended. For the changing the calling convention, see see GNU Fortran Compiler Directives.
因此,命名约定可能取决于编译器、编译器选项和操作系统。因此,如果使用给定的命名约定在 C++ 代码中声明函数,则 C++ 代码可能不可移植:在不同的计算机上或使用不同的编译器编译它可能会失败。
为了避免此类问题,存在一个名为 LAPACKE 的接口。该接口负责命名约定。最后,您需要做的就是通过 extern "C" { #include <lapacke.h>}
(在 C++ 中)包含 lapacke.h
,将 link 添加到 lapacke 并将 LAPACKE_
添加到 lapack 函数的名称之前。这是使用 dsyev()
:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
#include <time.h>
#include <lapacke.h>
int main(void){
int n=200;
srand(time(NULL));
// allocate the matrix, unpacked storage
double** A=malloc(n*sizeof(double*));
if(A==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
A[0]=malloc(n*n*sizeof(double));
if(A[0]==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
int i;
for(i=1;i<n;i++){
A[i]=&A[0][n*i];
}
//populte the matrix, only the lower diagonal part
int j;
for(i=0;i<n;i++){
for(j=0;j<i;j++){
A[i][j]=rand()/((double)RAND_MAX);
}
A[i][i]=rand()/((double)RAND_MAX)+42.;
}
//saving the matrix, because zheev() changes it.
double complex** As=malloc(n*sizeof(double complex*));
if(As==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
As[0]=malloc(n*n*sizeof(double complex));
if(As[0]==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
for(i=1;i<n;i++){
As[i]=&As[0][n*i];
}
for(i=0;i<n;i++){
for(j=0;j<i;j++){
As[i][j]=A[i][j];
}
As[i][i]=A[i][i];
}
//transpose part
for(i=0;i<n;i++){
for(j=i+1;j<n;j++){
As[i][j]=(A[j][i]);
}
}
//let's get the eigenvalues and the eigenvectors!
double* w=malloc(n*sizeof(double));
if(w==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
int lda = n;
int info = LAPACKE_dsyev(LAPACK_ROW_MAJOR, 'V', 'L', n, A[0], lda, w);
if(info<0){
fprintf(stderr,"argument %d has illegal value\n",-info);
}
if(info>0){
fprintf(stderr,"algorithm failed to converge... bad condition number ?\n");
}
//printing the eigenvalues...
for(i=0;i<n;i++){
printf("%d %g\n",i,w[i]);
}
//let's check that the column i of A is now a right eigenvectors corresponding to the eigenvalue w[i]...
int l=42;
double *res=malloc(n*sizeof(double));
if(res==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
for(i=0;i<n;i++){
res[i]=0;
for(j=0;j<n;j++){
res[i]+=As[i][j]*A[j][l];
}
res[i]-=w[l]*A[i][l];
}
double norm2res=0;
double norm2vec=0;
for(i=0;i<n;i++){
norm2res+=res[i]*res[i];
norm2vec+=A[i][l]*A[i][l];
}
printf("the norm of the eigenvector is %g\n",sqrt(norm2vec));
printf("||Ax-\lambda*x||_2/||x||_2 is about %g\n",sqrt(norm2res/norm2vec));
//free the matrix
free(A[0]);
free(A);
free(As[0]);
free(As);
free(w);
free(res);
return 0;
}
由gcc main.c -o main -llapacke -llapack -lblas -lm -Wall