对任意一个\(m\times n\)的实矩阵,总可以按照SVD算法对其进行分解。即:

\[A = U\Sigma V^T
\]

其中\(U、V\)分别为\(m\times m、n\times n\)的方阵,由\(A\)的左奇异向量和右奇异向量组成,且\(U\)与\(V\)均为正交阵。\(\Sigma\)为\(m\times n\)的对角矩阵,对角线上的元素为矩阵\(A\)的奇异值。

在MKL库中求解奇异值和奇异向量的函数为LAPACKE_dgesvd

1 参数详解

  1. lapack_int LAPACKE_dgesvd(
  2. matrix_layout, // (input)行优先(LAPACK_ROW_MAJOR)或列优先(LAPACK_COL_MAJOR)
  3. jobu, // (input)计算矩阵U的全部或部分并返回。
  4. /*"A":返回U的所有M列到U,
  5. "S":返回U的前min(m,n)列到U,
  6. "O":返回U的前min(m,n)列到A矩阵(覆盖),
  7. "N":不计算矩阵U*/
  8. jobvt, // (input)计算矩阵VT的全部或部分并返回;选项列表与jobu相同;
  9. m, // (input)A矩阵的行,m>=0
  10. n, // (input)A矩阵的列,n>=0
  11. a, // (input/output)A矩阵
  12. lda, // (input)A矩阵的第一维大小
  13. s, // (output)A矩阵的奇异值,并按照从大到小的顺序排列
  14. u, // (output) 矩阵U元素的一维数组
  15. ldu, // (input) U矩阵的第一维大小
  16. vt, // (output) 矩阵VT元素的一维数组
  17. ldvt, // (input) VT矩阵的第一维大小
  18. superb, // (output)工作空间
  19. )

2 定义待处理矩阵

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include "mkl_lapacke.h"
  4. #define min(a,b) ((a)>(b)?(b):(a))
  5. // 矩阵维度参数
  6. #define M 6
  7. #define N 5
  8. #define LDA N
  9. #define LDU M
  10. #define LDVT N
  1. // 声明需要的参数
  2. MKL_INT m = M, n = N, lda = LDA, ldu = LDU, ldvt = LDVT, info;
  3. double superb[min(M,N)-1];
  4. double s[N], u[LDU*M], vt[LDVT*N]; //声明奇异值与奇异向量
  5. double a[LDA*M] = { //定义待分解的A矩阵
  6. 8.79, 9.93, 9.83, 5.45, 3.16,
  7. 6.11, 6.91, 5.04, -0.27, 7.98,
  8. -9.15, -7.93, 4.86, 4.85, 3.01,
  9. 9.57, 1.64, 8.83, 0.74, 5.80,
  10. -3.49, 4.02, 9.80, 10.00, 4.27,
  11. 9.84, 0.15, -8.99, -6.02, -5.31
  12. };

3 执行SVD分解

  1. LAPACKE_dgesvd(LAPACK_ROW_MAJOR, 'A', 'A', m, n, a, lda, s, u, ldu, vt, ldvt, superb);

结果如图:

完整代码

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include "mkl_lapacke.h"
  4. #define min(a,b) ((a)>(b)?(b):(a))
  5. // 展示奇异向量
  6. extern void print_matrix(const char* desc, MKL_INT m, MKL_INT n, double* a, MKL_INT lda);
  7. #define M 6
  8. #define N 5
  9. #define LDA N
  10. #define LDU M
  11. #define LDVT N
  12. int main() {
  13. //声明、定义输入
  14. MKL_INT m = M, n = N, lda = LDA, ldu = LDU, ldvt = LDVT, info;
  15. double superb[min(M, N) - 1];
  16. double s[N], u[LDU * M], vt[LDVT * N];
  17. double a[LDA * M] = {
  18. 8.79, 9.93, 9.83, 5.45, 3.16,
  19. 6.11, 6.91, 5.04, -0.27, 7.98,
  20. -9.15, -7.93, 4.86, 4.85, 3.01,
  21. 9.57, 1.64, 8.83, 0.74, 5.80,
  22. -3.49, 4.02, 9.80, 10.00, 4.27,
  23. 9.84, 0.15, -8.99, -6.02, -5.31
  24. };
  25. printf("LAPACKE_dgesvd (row-major, high-level) Example Program Results\n");
  26. //计算SVD
  27. info = LAPACKE_dgesvd(LAPACK_ROW_MAJOR, 'A', 'A', m, n, a, lda,
  28. s, u, ldu, vt, ldvt, superb);
  29. if (info > 0) {
  30. printf("The algorithm computing SVD failed to converge.\n");
  31. exit(1);
  32. }
  33. //奇异值
  34. print_matrix("Singular values", 1, n, s, 1);
  35. //左奇异向量
  36. print_matrix("Left singular vectors (stored columnwise)", m, n, u, ldu);
  37. //右奇异向量
  38. print_matrix("Right singular vectors (stored rowwise)", n, n, vt, ldvt);
  39. exit(0);
  40. }
  41. void print_matrix(const char* desc, MKL_INT m, MKL_INT n, double* a, MKL_INT lda) {
  42. MKL_INT i, j;
  43. printf("\n %s\n", desc);
  44. for (i = 0; i < m; i++) {
  45. for (j = 0; j < n; j++) printf(" %6.2f", a[i * lda + j]);
  46. printf("\n");
  47. }
  48. }

补充:SVD分解求逆

由之前的介绍,对于任意的实数矩阵\(A\),可以进行SVD分解:

\[A = U\Sigma V^T\\
\]

其中,\(U\)、\(V^T\)为正交矩阵,\(\Sigma\)为对角矩阵。若\(A\)矩阵可逆,易得

\[A^{-1}=(U\Sigma V^T)^{-1}=V\Sigma^{-1}U^T
\]

即当使用LAPACKE_dgesvd,将矩阵\(A\)分解出三部分后,再经过简单的转置、对角阵求逆,最后通过LAPACKE_dgemm完成各矩阵相乘即可得到\(A\)的逆矩阵。

MKL库奇异值分解(LAPACKE_dgesvd)的更多相关文章

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

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

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

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

  3. MKL库矩阵乘法

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

  4. 科学计算库(BLAS,LAPACK,MKL,EIGEN)

    函数库接口标准:BLAS (Basic Linear Algebra Subprograms)和LAPACK (Linear Algebra PACKage) 1979年,Netlib首先用Fortr ...

  5. 64位Win7下安装并配置Python3的深度学习库:Theano

    注:本文全原创,作者:Noah Zhang  (http://www.cnblogs.com/noahzn/) 这两天在安装Python的深度学习库:Theano.尝试了好多遍,CMake.MinGW ...

  6. Linux C/C++ 链接选项之静态库--whole-archive,--no-whole-archive和--start-group, --end-group

    参照这两篇博客: http://stackoverflow.com/questions/805555/ld-linker-question-the-whole-archive-option http: ...

  7. MKL与VS2019配置方法

    VS2019配置oneAPI并调用MKL库 oneAPI oneAPI是一个跨架构的编程工具,旨在简化跨GPU.CPU.FPGA和AI加速器之间的编程,可以与英特尔自身设备,或其他厂商的芯片配合使用, ...

  8. Microsoft+R:Microsoft R Open (MRO)安装和多核运作

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 本文转载于公众号大猫的R语言课堂,公众号作者使 ...

  9. Caffe + Ubuntu 14.04 64bit + 无CUDA(linux下安装caffe(无cuda)以及python接口)

    安装Caffe指导书 环境: Linux 64位 显卡为Intel + AMD,非英伟达显卡 无GPU 一. 安装准备工作 1. 以管理员身份登录 在左上角点击图标,搜索terminal(即终端),以 ...

随机推荐

  1. ubuntu开启emqx/nginx/uwsgi自启动服务

    一.emqx开机自启 a.首先在执行如下命令  vi /lib/systemd/system/emqx.service 创建了emqx.service文件然后在文件中写入如下内容 [Unit] Des ...

  2. kafka-linux-install

    linux按照kafka 必须先按照java jdk包!!!!!!!!!!!! 先安装zookeeper 下载:http://mirrors.hust.edu.cn/apache/zookeeper/ ...

  3. chubby 是什么,和 zookeeper 比你怎么看?

    chubby 是 google 的,完全实现 paxos 算法,不开源.zookeeper 是 chubby的开源实现,使用 zab 协议,paxos 算法的变种.

  4. spring 支持哪些 ORM 框架?

    Hibernate iBatis JPA JDO· OJB

  5. -> 在c语言中是什么意思?

    ->在C语言中称为间接引用运算符,是二目运算符,优先级同成员运算符".".用法:p->a,其中p是指向一个结构体的指针,a是这个结构体类型的一个成员.表达式p-> ...

  6. 1_开环系统和闭环系统_反馈控制_Open/Closed Loop System_Feedback

  7. validator API文档

    如何使用 引入 <script src="../node_modules/jquery/dist/jquery.js"></script> <scri ...

  8. Qunee for HTML5 v1.6新版本发布

    Qunee for HTML5 V1.6正式发布,修复了一些 BUG,增加了滚动条支持,改进了编辑器,增加了JSON 导入导出.告警冒泡.连线流动,UI 定制等扩展示例,欢迎 访问 导航面板 增加了滚 ...

  9. Codepen 每日精选(2018-4-6)

    按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以打开原始页面. 按照画出的路线吃豆子的交互动画https://codepen.io/createjs/f... 模拟真实手 ...

  10. c++实现职责链模式--财务审批

    内容: 某物资管理系统中物资采购需要分级审批,主任可以审批1万元及以下的采购单,部门经理可以审批5万元及以下的采购单,副总经理可以审批10万元及以下的采购单,总经理可以审批20万元及以下的采购单,20 ...