test-svd0.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // SVD dimensionality reduction
  2. #include <float.h>
  3. #include <stdint.h>
  4. #include <stdio.h>
  5. #include <assert.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <time.h>
  9. #include <math.h>
  10. #include <sys/time.h>
  11. #ifdef GGML_USE_ACCELERATE
  12. #include <Accelerate/Accelerate.h>
  13. #endif
  14. float frand() {
  15. return (float) rand() / (float) RAND_MAX;
  16. }
  17. //int sgesvd_(char *__jobu, char *__jobvt, __CLPK_integer *__m,
  18. // __CLPK_integer *__n, __CLPK_real *__a, __CLPK_integer *__lda,
  19. // __CLPK_real *__s, __CLPK_real *__u, __CLPK_integer *__ldu,
  20. // __CLPK_real *__vt, __CLPK_integer *__ldvt, __CLPK_real *__work,
  21. // __CLPK_integer *__lwork,
  22. // __CLPK_integer *__info)
  23. int main(int argc, const char ** argv) {
  24. int m = 10;
  25. int n = 5;
  26. float * A = malloc(n * m * sizeof(float));
  27. float * A0 = malloc(n * m * sizeof(float));
  28. for (int i = 0; i < n; ++i) {
  29. for (int j = 0; j < m; ++j) {
  30. A[i * m + j] = (float) (10.0f*(i + 1) + 1.0f * frand());
  31. //A[i * m + j] = (float) (10.0f*(i%2 + 1) + 0.1f * frand());
  32. //if (i == 2) {
  33. // A[i * m + j] += 20*frand();
  34. //}
  35. if ((i == 1 || i == 3) && j > m/2) {
  36. A[i * m + j] = -A[i * m + j];
  37. }
  38. }
  39. }
  40. // average vector
  41. //float * M = malloc(m * sizeof(float));
  42. //{
  43. // for (int j = 0; j < m; ++j) {
  44. // M[j] = 0.0f;
  45. // }
  46. // for (int i = 0; i < n; ++i) {
  47. // for (int j = 0; j < m; ++j) {
  48. // M[j] += A[i * m + j];
  49. // }
  50. // }
  51. // for (int j = 0; j < m; ++j) {
  52. // M[j] /= (float) n;
  53. // }
  54. //}
  55. //// subtract average vector
  56. //for (int i = 0; i < n; ++i) {
  57. // for (int j = 0; j < m; ++j) {
  58. // A[i * m + j] -= M[j];
  59. // }
  60. //}
  61. memcpy(A0, A, n * m * sizeof(float));
  62. // print A
  63. printf("A:\n");
  64. for (int i = 0; i < n; ++i) {
  65. printf("col %d : ", i);
  66. for (int j = 0; j < m; ++j) {
  67. printf("%9.5f ", A[i * m + j]);
  68. }
  69. printf("\n");
  70. }
  71. printf("\n");
  72. // SVD
  73. // A = U * S * V^T
  74. float * U = malloc(n * m * sizeof(float));
  75. float * S = malloc(n * sizeof(float));
  76. float * V = malloc(n * n * sizeof(float));
  77. int lda = m;
  78. int ldu = m;
  79. int ldvt = n;
  80. float work_size;
  81. int lwork = -1;
  82. int info = 0;
  83. sgesvd_("S", "S", &m, &n, A, &lda, S, U, &ldu, V, &ldvt, &work_size, &lwork, &info);
  84. lwork = (int) work_size;
  85. printf("work_size = %f, info = %d, lwork = %d\n", work_size, info, lwork);
  86. float * work = malloc(lwork * sizeof(float));
  87. sgesvd_("S", "S", &m, &n, A, &lda, S, U, &ldu, V, &ldvt, work, &lwork, &info);
  88. // print U
  89. printf("U:\n");
  90. for (int i = 0; i < n; ++i) {
  91. printf("col %d : ", i);
  92. for (int j = 0; j < m; ++j) {
  93. printf("%9.5f ", U[i * m + j]);
  94. }
  95. printf("\n");
  96. }
  97. printf("\n");
  98. // normalize S
  99. {
  100. double sum = 0.0;
  101. for (int i = 0; i < n; ++i) {
  102. sum += S[i];
  103. }
  104. sum *= sqrt((double) m);
  105. for (int i = 0; i < n; ++i) {
  106. S[i] /= sum;
  107. }
  108. }
  109. // print S
  110. printf("S:\n");
  111. for (int i = 0; i < n; ++i) {
  112. printf("- %d = %9.5f\n", i, S[i]);
  113. }
  114. printf("\n");
  115. // print V
  116. printf("V:\n");
  117. for (int i = 0; i < n; ++i) {
  118. printf("col %d : ", i);
  119. for (int j = 0; j < n; ++j) {
  120. printf("%9.5f ", V[i * n + j]);
  121. }
  122. printf("\n");
  123. }
  124. printf("\n");
  125. // print A
  126. printf("A:\n");
  127. for (int i = 0; i < n; ++i) {
  128. printf("col %d : ", i);
  129. for (int j = 0; j < m; ++j) {
  130. printf("%9.5f ", A[i * m + j]);
  131. }
  132. printf("\n");
  133. }
  134. printf("\n");
  135. // compute singular vectors in U
  136. for (int i = 0; i < n; ++i) {
  137. for (int j = 0; j < m; ++j) {
  138. U[i * m + j] *= S[i];
  139. }
  140. }
  141. // normalize U
  142. for (int i = 0; i < n; ++i) {
  143. double sum = 0.0;
  144. for (int j = 0; j < m; ++j) {
  145. sum += U[i * m + j] * U[i * m + j];
  146. }
  147. sum = sqrt(sum);
  148. for (int j = 0; j < m; ++j) {
  149. U[i * m + j] /= sum*sqrt((double) m);
  150. }
  151. }
  152. // print U
  153. printf("U:\n");
  154. for (int i = 0; i < n; ++i) {
  155. printf("col %d : ", i);
  156. for (int j = 0; j < m; ++j) {
  157. printf("%9.5f ", U[i * m + j]);
  158. }
  159. printf("\n");
  160. }
  161. printf("\n");
  162. // project A0 onto U
  163. float * A1 = malloc(n * n * sizeof(float));
  164. for (int i = 0; i < n; ++i) {
  165. for (int j = 0; j < n; ++j) {
  166. A1[i * n + j] = 0.0f;
  167. for (int k = 0; k < m; ++k) {
  168. A1[i * n + j] += A0[i * m + k] * U[j * m + k];
  169. }
  170. }
  171. }
  172. // print A1
  173. printf("A1:\n");
  174. for (int i = 0; i < n; ++i) {
  175. printf("col %d : ", i);
  176. for (int j = 0; j < n; ++j) {
  177. printf("%9.5f ", A1[i * n + j]);
  178. }
  179. printf("\n");
  180. }
  181. printf("\n");
  182. return 0;
  183. }