接上一篇。。。

下面我们将 SVD 相关的功能封装成一个类,以方便我们提取 S 和 V 的值。

另外,当我们一个 A 有多组 x 需要求解时,也只需要计算一次 SVD 分解,用下面的类能减少很多计算量。

头文件如下:

  1. #ifndef GSLSINGULARVALUEDECOMPOSITION_H
  2. #define GSLSINGULARVALUEDECOMPOSITION_H
  3. #include <gsl/gsl_matrix.h>
  4. #include <gsl/gsl_vector.h>
  5. #include <gsl/gsl_blas.h>
  6. #include <gsl/gsl_linalg.h>
  7. #include <gsl/gsl_errno.h>
  8. void linearSolve_SVD(const gsl_matrix * A, const gsl_vector * b, gsl_vector * x);
  9. class GslSVD
  10. {
  11. public:
  12. GslSVD();
  13. ~GslSVD();
  14. int SV_decomp(const gsl_matrix * A);
  15. int SV_decomp_mod(const gsl_matrix * A);
  16. int SV_decomp_jacobi (gsl_matrix * A);
  17. int SV_solve(const gsl_vector *b, gsl_vector *x);
  18. gsl_vector * getVectorS();
  19. gsl_matrix * getMatrixU();
  20. gsl_matrix * getMatrixV();
  21. int trimVectorS(double abseps);
  22. private:
  23. gsl_vector * S;
  24. gsl_matrix * U;
  25. gsl_matrix * V;
  26. void alloc_suv(int rows, int cols);
  27. };
  28. #endif // GSLSINGULARVALUEDECOMPOSITION_H

程序文件如下:

  1. #include "gsl_SVD.h"
  2. void linearSolve_SVD(const gsl_matrix * A, const gsl_vector * b, gsl_vector * x)
  3. {
  4. int rows = A->size1;
  5. int cols = A->size2;
  6. gsl_vector * work = gsl_vector_alloc (cols);
  7. gsl_vector * S = gsl_vector_alloc (cols);
  8. gsl_matrix * U = gsl_matrix_alloc(rows, cols);;
  9. gsl_matrix * V = gsl_matrix_alloc(cols, cols);
  10. gsl_matrix_memcpy (U, A); // 为了不破坏 A 中原始的数据,这里全都拷贝到 U 中
  11. gsl_linalg_SV_decomp( U, V, S, work );
  12. gsl_linalg_SV_solve ( U, V, S, b, x );
  13. gsl_vector_free(work);
  14. gsl_vector_free(S);
  15. gsl_matrix_free(V);
  16. gsl_matrix_free(U);
  17. }
  18. int GslSVD::trimVectorS(double abseps)
  19. {
  20. int count = 0;
  21. for(int i = 0; i < S->size; i++)
  22. {
  23. if(fabs(gsl_vector_get(S, i)) < abseps)
  24. {
  25. count ++;
  26. gsl_vector_set(S, i, 0);
  27. }
  28. }
  29. return count;
  30. }
  31. gsl_vector * GslSVD::getVectorS()
  32. {
  33. if(S == NULL) return NULL;
  34. gsl_vector * s = gsl_vector_alloc(S->size);
  35. gsl_vector_memcpy(s, S);
  36. return s;
  37. }
  38. gsl_matrix * GslSVD::getMatrixU()
  39. {
  40. if(U == NULL) return NULL;
  41. gsl_matrix * u = gsl_matrix_alloc(U->size1, U->size2);
  42. gsl_matrix_memcpy(u, U);
  43. return u;
  44. }
  45. gsl_matrix * GslSVD::getMatrixV()
  46. {
  47. if(V == NULL) return NULL;
  48. gsl_matrix * v = gsl_matrix_alloc(V->size1, V->size2);
  49. gsl_matrix_memcpy(v, V);
  50. return v;
  51. }
  52. GslSVD::GslSVD()
  53. {
  54. S = NULL;
  55. U = NULL;
  56. V = NULL;
  57. }
  58. void GslSVD::alloc_suv(int rows, int cols)
  59. {
  60. if( S != NULL )
  61. {
  62. gsl_vector_free(S);
  63. gsl_matrix_free(U);
  64. gsl_matrix_free(V);
  65. }
  66. S = gsl_vector_alloc (cols);
  67. U = gsl_matrix_alloc(rows, cols);
  68. V = gsl_matrix_alloc(cols, cols);
  69. }
  70. int GslSVD::SV_decomp(const gsl_matrix * A)
  71. {
  72. int rows = A->size1;
  73. int cols = A->size2;
  74. gsl_vector * work = gsl_vector_alloc (cols);
  75. alloc_suv(rows, cols);
  76. gsl_matrix_memcpy (U, A); // 为了不破坏 A 中原始的数据,这里全都拷贝到 U 中
  77. int ret = gsl_linalg_SV_decomp( U, V, S, work );
  78. gsl_vector_free(work);
  79. return ret;
  80. }
  81. int GslSVD::SV_decomp_mod(const gsl_matrix * A)
  82. {
  83. int rows = A->size1;
  84. int cols = A->size2;
  85. gsl_vector * work = gsl_vector_alloc (cols);
  86. gsl_matrix *X = gsl_matrix_alloc(cols, cols);
  87. alloc_suv(rows, cols);
  88. gsl_matrix_memcpy (U, A); // 为了不破坏 A 中原始的数据,这里全都拷贝到 U 中
  89. int ret = gsl_linalg_SV_decomp_mod( U, X, V, S, work );
  90. gsl_matrix_free(X);
  91. gsl_vector_free(work);
  92. return ret;
  93. }
  94. int GslSVD::SV_decomp_jacobi (gsl_matrix * A)
  95. {
  96. int rows = A->size1;
  97. int cols = A->size2;
  98. alloc_suv(rows, cols);
  99. gsl_matrix_memcpy (U, A); // 为了不破坏 A 中原始的数据,这里全都拷贝到 U 中
  100. int ret = gsl_linalg_SV_decomp_jacobi( U, V, S );
  101. return ret;
  102. }
  103. int GslSVD::SV_solve(const gsl_vector *b, gsl_vector *x)
  104. {
  105. if(U != NULL)
  106. {
  107. return gsl_linalg_SV_solve (U, V, S, b, x);
  108. }
  109. return -1;
  110. }
  111. GslSVD::~GslSVD()
  112. {
  113. if(S != NULL)
  114. {
  115. gsl_vector_free(S);
  116. gsl_matrix_free(V);
  117. gsl_matrix_free(U);
  118. }
  119. }

下面是个简单的测试代码:

  1. void test5()
  2. {
  3. double a_data[] = {1, 2,
  4. 2, 4};
  5. gsl_matrix_view A = gsl_matrix_view_array (a_data, 2, 2);
  6. GslSVD svd;
  7. svd.SV_decomp(&A.matrix);
  8. puts("S = ");
  9. gsl_vector_fprintf (stdout, svd.getVectorS(), "%f");
  10. puts("\nV = ");
  11. gsl_matrix_fprintf (stdout, svd.getMatrixV(), "%f");
  12. double b_data[] = {3, 6};
  13. gsl_vector_view b = gsl_vector_view_array (b_data, 2);
  14. gsl_vector * x = gsl_vector_alloc (2);
  15. svd.SV_solve(&b.vector, x);
  16. puts("\nx = ");
  17. gsl_vector_fprintf (stdout, x, "%f");
  18. }

用 GSL 求解超定方程组及矩阵的奇异值分解(SVD) 2的更多相关文章

  1. 用 GSL 求解超定方程组及矩阵的奇异值分解(SVD)

    用 GSL 求解超定方程组及矩阵的奇异值分解(SVD) 最近在学习高动态图像(HDR)合成的算法,其中需要求解一个超定方程组,因此花了点时间研究了一下如何用 GSL 来解决这个问题. GSL 里是有最 ...

  2. Python最小二乘法解非线性超定方程组

    求解非线性超定方程组,网上搜到的大多是线性方程组的最小二乘解法,对于非线性方程组无济于事. 这里分享一种方法:SciPy库的scipy.optimize.leastsq函数. import numpy ...

  3. 小游戏 Lights Out (关灯) 的求解 —— 异或方程组

    Author : Evensgn  Blog Link : http://www.cnblogs.com/JoeFan/ Article Link : http://www.cnblogs.com/J ...

  4. 高斯消元法求解异或方程组: cojs.tk 539.//BZOJ 1770 牛棚的灯

    高斯消元求解异或方程组: 比较不错的一篇文章:http://blog.sina.com.cn/s/blog_51cea4040100g7hl.html cojs.tk  539. 牛棚的灯 ★★☆   ...

  5. 【poj1830-开关问题】高斯消元求解异或方程组

    第一道高斯消元题目~ 题目:有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关 ...

  6. 机器学习降维方法概括, LASSO参数缩减、主成分分析PCA、小波分析、线性判别LDA、拉普拉斯映射、深度学习SparseAutoEncoder、矩阵奇异值分解SVD、LLE局部线性嵌入、Isomap等距映射

    机器学习降维方法概括   版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u014772862/article/details/52335970 最近 ...

  7. 矩阵奇异值分解(SVD)及其应用

    机器学习中的数学(5)-强大的矩阵奇异值分解(SVD)及其应用(好文) [简化数据]奇异值分解(SVD) <数学之美> 第15章 矩阵运算和文本处理中的两个分类问题

  8. 矩阵的奇异值分解(SVD)(理论)

    矩阵的奇异值分解(Singular Value Decomposition,SVD)是数值计算中的精彩之处,在其它数学领域和机器学习领域得到了广泛的应用,如矩阵的广义逆,主分成分析(PCA),自然语言 ...

  9. 奇异值分解(SVD)和最小二乘解在解齐次线性超定方程中的应用

    奇异值分解,是在A不为方阵时的对特征值分解的一种拓展.奇异值和特征值的重要意义相似,都是为了提取出矩阵的主要特征. 对于齐次线性方程 A*X =0;当A的秩大于列数时,就需要求解最小二乘解,在||X| ...

随机推荐

  1. SQL 中Count()的问题

    假如一张表中有如下的数据: 当使用select Count(*) from TableName表示获取表中数据记录的条数: 有时候可以通过select Count(列名) from TableName ...

  2. 用Model来计算cell的高度

    用Model来计算cell的高度 效果: 将计算cell高度的方法直接移植到Model当中,初始化的瞬间就计算好了高度,非常好用! 源码: Model // // Model.h // // Copy ...

  3. 测试SDWebImage淡入淡出效果在UITableView中的重用显示问题

    测试SDWebImage淡入淡出效果在UITableView中的重用显示问题 这个是在上一篇教程的基础上所添加的测试环节! 效果图(从效果图中看是没有任何重用问题的): 源码: ImageCell.h ...

  4. 屏蔽响应事件继续向父视图传递的category

    屏蔽响应事件继续向父视图传递的category 这篇教程是上一篇教程的升级版,将复杂的代码封装成了category,更便于使用:) 效果: 源码: UIGestureRecognizer+EnvetI ...

  5. UNIX高级环境编程(4)Files And Directories - umask、chmod、文件系统组织结构和链接

    本篇主要介绍文件和文件系统中常用的一些函数,文件系统的组织结构和硬链接.符号链接. 通过对这些知识的了解,可以对Linux文件系统有更为全面的了解.   1 umask函数 之前我们已经了解了每个文件 ...

  6. September 02nd 2017 Week 35th Saturday

    Some things are more precious because they don't last long. 有些东西之所以弥足珍贵,是因为它们总是昙花一现. Life is ephemer ...

  7. Zepto的SwipeUp 在 android 和微信 的解决方案

    Zepto的SwipeUp 在 android 和微信 的解决方案 时间:2016-04-19 22:20:09 作者:zhongxia 问题解决方案: Q:为什么swipeUp和swipeDown在 ...

  8. extjs_05_grid(表格分组)

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWRhbV93enM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...

  9. Kubernetes-dns 域名解析问题

    问题描述:nginx不能解析域名,但是使用nslookup却可以解析域名 ./sbin/nginx -t nginx: [emerg] host not found in upstream " ...

  10. Alpha冲刺(5/10)——追光的人

    1.队友信息 队员学号 队员博客 221600219 小墨 https://www.cnblogs.com/hengyumo/ 221600240 真·大能猫 https://www.cnblogs. ...