LAPACK(Linear Algebra PACKage)库,是用Fortran语言编写的线性代数计算库,包含线性方程组求解(\(AX=B\))、矩阵分解、矩阵求逆、求矩阵特征值、奇异值等。该库用BLAS库做底层运算。

本示例将重点介绍使用LAPACK库求解非对称矩阵与对称矩阵的特征值、特征向量过程。

1 一般矩阵

在LAPACK库中,使用?geev函数计算一般矩阵的特征值及其左/右特征向量,其中右特征向量\(v_j\)满足

\[A*v_j = \lambda_j*v_j
\]

左特征向量\(u_j\)满足

\[u_j^H*A = \lambda_j*u_j^H
\]

其中\(u_j^H\)表示\(u_j\)的共轭转置。

1.1 参数详解

示例将使用MKL库中,LAPACK中的dgeev函数演示。

lapack_int LAPACKE_dgeev( matrix_order,     //(input) 行优先(LAPACK_ROW_MAJOR)或列优先(LAPACK_COL_MAJOR)
jobvl, //(input) 指定是否计算左特征向量,"V":计算;"N":不计算
jobvr, //(input) 指定是否计算右特征向量,同上
n, //(input) 矩阵的阶数
a, //(input/output) 待求解A矩阵
lda, //(input) A矩阵的第一维
wr, //(output) 特征向量实部
wi, //(output) 特征向量虚部
vl, //(output) 左特征向量
ldvl, //(input) 左特征向量第一维
vr, //(output) 右特征向量
ldvr //(input) 右特征向量第一维
)

1.2 定义待求解矩阵

#include <stdlib.h>
#include <stdio.h>
#include "mkl_lapacke.h" // 参数
#define N 5
#define LDA N
#define LDVL N
#define LDVR N
MKL_INT n = N, lda = LDA, ldvl = LDVL, ldvr = LDVR, info;

double wr[N], wi[N], vl[LDVL*N], vr[LDVR*N];
double a[LDA*N] = {
-1.01, 0.86, -4.60, 3.31, -4.81,
3.98, 0.53, -7.04, 5.29, 3.55,
3.30, 8.26, -3.89, 8.20, -1.51,
4.43, 4.96, -7.66, -7.33, 6.18,
7.31, -6.43, -6.16, 2.47, 5.58
};

1.3 求解特征值、特征向量

LAPACKE_dgeev( LAPACK_ROW_MAJOR, 'V', 'V', n, a, lda, wr, wi, vl, ldvl, vr, ldvr );

与Matlab中使用eig方法求取特征值与特征向量,所得结果相同。

A = [  -1.01,  0.86, -4.60,  3.31, -4.81;
3.98, 0.53, -7.04, 5.29, 3.55;
3.30, 8.26, -3.89, 8.20, -1.51;
4.43, 4.96, -7.66, -7.33, 6.18;
7.31, -6.43, -6.16, 2.47, 5.58];
[V,D]=eig(A);
Vector = V;
Lambda = diag(D);
display(Lambda);
display(Vector);

完整代码

#include <stdlib.h>
#include <stdio.h>
#include "mkl_lapacke.h" //print特征值和特征向量
extern void print_eigenvalues( char* desc, MKL_INT n, double* wr, double* wi );
extern void print_eigenvectors( char* desc, MKL_INT n, double* wi, double* v,
MKL_INT ldv ); #define N 5
#define LDA N
#define LDVL N
#define LDVR N int main() { MKL_INT n = N, lda = LDA, ldvl = LDVL, ldvr = LDVR, info; double wr[N], wi[N], vl[LDVL*N], vr[LDVR*N];
double a[LDA*N] = {
-1.01, 0.86, -4.60, 3.31, -4.81,
3.98, 0.53, -7.04, 5.29, 3.55,
3.30, 8.26, -3.89, 8.20, -1.51,
4.43, 4.96, -7.66, -7.33, 6.18,
7.31, -6.43, -6.16, 2.47, 5.58
}; printf( "LAPACKE_dgeev (row-major, high-level) Example Program Results\n" );
// 求解
info = LAPACKE_dgeev( LAPACK_ROW_MAJOR, 'V', 'V', n, a, lda, wr, wi,
vl, ldvl, vr, ldvr ); if( info > 0 ) {
printf( "The algorithm failed to compute eigenvalues.\n" );
exit( 1 );
} print_eigenvalues( "Eigenvalues", n, wr, wi ); print_eigenvectors( "Left eigenvectors", n, wi, vl, ldvl ); print_eigenvectors( "Right eigenvectors", n, wi, vr, ldvr );
exit( 0 );
} void print_eigenvalues( char* desc, MKL_INT n, double* wr, double* wi ) {
MKL_INT j;
printf( "\n %s\n", desc );
for( j = 0; j < n; j++ ) {
if( wi[j] == (double)0.0 ) {
printf( " %6.2f", wr[j] );
} else {
printf( " (%6.2f,%6.2f)", wr[j], wi[j] );
}
}
printf( "\n" );
} void print_eigenvectors( char* desc, MKL_INT n, double* wi, double* v, MKL_INT ldv ) {
MKL_INT i, j;
printf( "\n %s\n", desc );
for( i = 0; i < n; i++ ) {
j = 0;
while( j < n ) {
if( wi[j] == (double)0.0 ) {
printf( " %6.2f", v[i*ldv+j] );
j++;
} else {
printf( " (%6.2f,%6.2f)", v[i*ldv+j], v[i*ldv+(j+1)] );
printf( " (%6.2f,%6.2f)", v[i*ldv+j], -v[i*ldv+(j+1)] );
j += 2;
}
}
printf( "\n" );
}
}

2 求解对称阵

2.1 参数详解

采用LAPACKE_dsyev方法实现,参数比LAPACKE_dgeev少,含义相似。

lapack_int LAPACKE_dsyev(	matrix_layout,
jobz, //是否计算特征值和特征向量, "V"/"N"
uplo, //表示使用A矩阵的上三角或下三角矩阵 "U"/"L"
n,
a,
lda,
w //包含降序的特征值
)

完整代码

#include <stdlib.h>
#include <stdio.h>
#include "mkl_lapacke.h" extern void print_matrix(const char* desc, MKL_INT m, MKL_INT n, double* a, MKL_INT lda); #define N 5
#define LDA N int main() { MKL_INT n = N, lda = LDA, info; double w[N];
double a[LDA * N] = {
1.96, - 6.49, - 0.47, - 7.20, - 0.65,
-6.49, 3.80, - 6.39, 1.50, - 6.34,
-0.47, - 6.39, 4.17, - 1.51, 2.67,
-7.20, 1.50, - 1.51, 5.70, 1.80,
-0.65, - 6.34, 2.67, 1.80, - 7.10,
}; printf("LAPACKE_dsyev (row-major, high-level) Example Program Results\n");
//求解特征值、特征向量
info = LAPACKE_dsyev(LAPACK_ROW_MAJOR, 'V', 'U', n, a, lda, w); //'U'表示下三角 if (info > 0) {
printf("The algorithm failed to compute eigenvalues.\n");
exit(1);
} print_matrix("Eigenvalues", 1, n, w, 1); print_matrix("Eigenvectors (stored columnwise)", n, n, a, lda);
exit(0);
} void print_matrix(const char* desc, MKL_INT m, MKL_INT n, double* a, MKL_INT lda) {
MKL_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 * lda + j]);
printf("\n");
}
}

输出为:

MKL库求解矩阵特征值、特征向量(LAPACKE_dgeev、dsyev)的更多相关文章

  1. 采用梯度下降优化器(Gradient Descent optimizer)结合禁忌搜索(Tabu Search)求解矩阵的全部特征值和特征向量

    [前言] 对于矩阵(Matrix)的特征值(Eigens)求解,采用数值分析(Number Analysis)的方法有一些,我熟知的是针对实对称矩阵(Real Symmetric Matrix)的特征 ...

  2. MKL库矩阵乘法

    此示例是利用Intel 的MKL库函数计算矩阵的乘法,目标为:\(C=\alpha*A*B+\beta*C\),由函数cblas_dgemm实现: 其中\(A\)为\(m\times k\)维矩阵,\ ...

  3. 使用MTL库求解最小二乘解

    最小二乘计算最优解不管是哪个行业肯定都用到的非常多.对于遥感图像处理中,尤其是对图像进行校正处理,关于控制点的几种校正模型中,都用到最小二乘来计算模型的系数.比如几何多项式,或者通过GCP求解RPC系 ...

  4. MKL库奇异值分解(LAPACKE_dgesvd)

    对任意一个\(m\times n\)的实矩阵,总可以按照SVD算法对其进行分解.即: \[A = U\Sigma V^T \] 其中\(U.V\)分别为\(m\times m.n\times n\)的 ...

  5. [转]Numpy使用MKL库提升计算性能

    from:http://unifius.wordpress.com.cn/archives/5 系统:Gentoo Linux (64bit, Kernel 3.7.1)配置:Intel(R) Cor ...

  6. 如何在 code blocks中使用 mkl库

    为了安装caffe, 所以安装了mkl, 现在想在codeblock的项目中使用mkl. 设置mkl环境变量: mkl安装好后默认是在/opt/intel/mkl中,其中/opt/intel/mkl/ ...

  7. c语言计算矩阵特征值和特征向量-1(幂法)

    #include <stdio.h> #include <math.h> #include <stdlib.h> #define M 3 //方阵的行数 列数 #d ...

  8. 讲一下numpy的矩阵特征值分解与奇异值分解

    1.特征值分解 主要还是调包: from numpy.linalg import eig 特征值分解:  A = P*B*PT  当然也可以写成 A = QT*B*Q  其中B为对角元为A的特征值的对 ...

  9. PCA算法是怎么跟协方差矩阵/特征值/特征向量勾搭起来的?

    PCA, Principle Component Analysis, 主成份分析, 是使用最广泛的降维算法. ...... (关于PCA的算法步骤和应用场景随便一搜就能找到了, 所以这里就不说了. ) ...

  10. 特征值 特征向量 正交分解 PCA

    无意间想到的,有时间会补充内容. 还记得学线性代数时计算矩阵的特征值和特征向量,然后这个矩阵就可以用这个特征值和特征向量表示. 这样就可以理解成矩阵其实是多个向量拼在一起的,这样就可以将矩阵和向量建立 ...

随机推荐

  1. 在Unity中实现(纯C#)热更新--使用ILRunTime{学习日志}

    热更新的逻辑:热更新的那部分内容其实就是一个dll的库文件,到时候修改也是改这个库文件: 我们只需要在主工程(我们的Unity项目)中引入并调用这个dll库里的代码就行了. 首先我们需要在Unity中 ...

  2. 张高兴的大模型开发实战:(四)使用 LangGraph 实现多智能体应用

    目录 环境搭建与配置 定义智能体 加载模型 提取关键词 生成回答 连接智能体 定义图的状态 定义节点方法 根据指令路由 生成回答 文件处理 提取关键词 网络搜索 定义图的结构 运行图 运行指南 在控制 ...

  3. Unity3D教程:次表面散射的简单实现

    次表面散射指的是光线射入半透明材质,在内部发生散射后再透射出来的光线传播过程,考虑到有些项目会需要使用次表面散射,下面就给大家介绍下在Unity3D中次表面散射的简单实现,希望可以帮到大家. 一.前言 ...

  4. Git命令的全家福手册

    一.全局命令

  5. jmeter实现幂等测试的一种方法(案例)

    最近在研究怎样对电商系统的业务进行幂等测试,利用jmeter对单独业务开展幂等测试可能简便.直接有效吧 场景描述:买家每一笔订单选中商品后,系统会生成一个"ShopCartIds" ...

  6. python筛选出指定文件夹内后缀名为“xx”的文件

    如下图,筛选出下面文件夹内后缀为pdf的文件,且打印出文件名 代码如下:关键的一句,if file.endswith('pdf'),即获取的文件名如果后缀是pdf import os path = & ...

  7. Java 中有哪些垃圾回收算法?

    Java 中的垃圾回收算法 Java 中的垃圾回收(Garbage Collection,GC)机制通过多种算法实现对堆内存的管理.以下是常见的垃圾回收算法: 1. 标记-清除算法(Mark-Swee ...

  8. Visual Studio 2022 划词翻译插件!该插件可以方便地翻译变量名、类名、方法名等单词,帮助您更轻松地理解和使用代码。

    EnTranslate一款简单的划词翻译插件 简介 支持划词翻译(鼠标悬浮到单词上方将自动翻译) 支持播放单词发音 支持调用在线接口翻译 强大的单词拆分能力: 支持驼峰, 下划线形式等各种单词拆分 丰 ...

  9. 通过远程连接,docker访问获取数据表信息

    <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId&g ...

  10. div中文本超过指定宽度自动换行

    一.场景 因为想要一个页面显示完所有的文本,所以要进行文本处理 二.代码 宽度超过1800px就自动换行 <div style="word-break: break-all; word ...