| |
|
|
| #include <float.h> |
| #include <stdint.h> |
| #include <stdio.h> |
| #include <assert.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <time.h> |
| #include <math.h> |
|
|
| #include <sys/time.h> |
|
|
| #ifdef GGML_USE_ACCELERATE |
| #include <Accelerate/Accelerate.h> |
| #endif |
|
|
| float frand(void) { |
| return (float) rand() / (float) RAND_MAX; |
| } |
|
|
| |
| |
| |
| |
| |
| |
|
|
| int main(int argc, const char ** argv) { |
| int m = 10; |
| int n = 5; |
|
|
| float * A = malloc(n * m * sizeof(float)); |
| float * A0 = malloc(n * m * sizeof(float)); |
|
|
| for (int i = 0; i < n; ++i) { |
| for (int j = 0; j < m; ++j) { |
| A[i * m + j] = (float) (10.0f*(i + 1) + 1.0f * frand()); |
| |
| |
| |
| |
| if ((i == 1 || i == 3) && j > m/2) { |
| A[i * m + j] = -A[i * m + j]; |
| } |
| } |
| } |
|
|
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
|
|
| memcpy(A0, A, n * m * sizeof(float)); |
|
|
| |
| printf("A:\n"); |
| for (int i = 0; i < n; ++i) { |
| printf("col %d : ", i); |
| for (int j = 0; j < m; ++j) { |
| printf("%9.5f ", A[i * m + j]); |
| } |
| printf("\n"); |
| } |
| printf("\n"); |
|
|
| |
| |
|
|
| float * U = malloc(n * m * sizeof(float)); |
| float * S = malloc(n * sizeof(float)); |
| float * V = malloc(n * n * sizeof(float)); |
|
|
| int lda = m; |
| int ldu = m; |
| int ldvt = n; |
|
|
| float work_size; |
| int lwork = -1; |
| int info = 0; |
|
|
| sgesvd_("S", "S", &m, &n, A, &lda, S, U, &ldu, V, &ldvt, &work_size, &lwork, &info); |
|
|
| lwork = (int) work_size; |
|
|
| printf("work_size = %f, info = %d, lwork = %d\n", work_size, info, lwork); |
|
|
| float * work = malloc(lwork * sizeof(float)); |
|
|
| sgesvd_("S", "S", &m, &n, A, &lda, S, U, &ldu, V, &ldvt, work, &lwork, &info); |
|
|
| |
| printf("U:\n"); |
| for (int i = 0; i < n; ++i) { |
| printf("col %d : ", i); |
| for (int j = 0; j < m; ++j) { |
| printf("%9.5f ", U[i * m + j]); |
| } |
| printf("\n"); |
| } |
| printf("\n"); |
|
|
| |
| { |
| double sum = 0.0; |
| for (int i = 0; i < n; ++i) { |
| sum += S[i]; |
| } |
| sum *= sqrt((double) m); |
| for (int i = 0; i < n; ++i) { |
| S[i] /= sum; |
| } |
| } |
|
|
| |
| printf("S:\n"); |
| for (int i = 0; i < n; ++i) { |
| printf("- %d = %9.5f\n", i, S[i]); |
| } |
| printf("\n"); |
|
|
| |
| printf("V:\n"); |
| for (int i = 0; i < n; ++i) { |
| printf("col %d : ", i); |
| for (int j = 0; j < n; ++j) { |
| printf("%9.5f ", V[i * n + j]); |
| } |
| printf("\n"); |
| } |
| printf("\n"); |
|
|
| |
| printf("A:\n"); |
| for (int i = 0; i < n; ++i) { |
| printf("col %d : ", i); |
| for (int j = 0; j < m; ++j) { |
| printf("%9.5f ", A[i * m + j]); |
| } |
| printf("\n"); |
| } |
| printf("\n"); |
|
|
| |
| for (int i = 0; i < n; ++i) { |
| for (int j = 0; j < m; ++j) { |
| U[i * m + j] *= S[i]; |
| } |
| } |
|
|
| |
| for (int i = 0; i < n; ++i) { |
| double sum = 0.0; |
| for (int j = 0; j < m; ++j) { |
| sum += U[i * m + j] * U[i * m + j]; |
| } |
| sum = sqrt(sum); |
| for (int j = 0; j < m; ++j) { |
| U[i * m + j] /= sum*sqrt((double) m); |
| } |
| } |
|
|
| |
| printf("U:\n"); |
| for (int i = 0; i < n; ++i) { |
| printf("col %d : ", i); |
| for (int j = 0; j < m; ++j) { |
| printf("%9.5f ", U[i * m + j]); |
| } |
| printf("\n"); |
| } |
| printf("\n"); |
|
|
|
|
| |
| float * A1 = malloc(n * n * sizeof(float)); |
|
|
| for (int i = 0; i < n; ++i) { |
| for (int j = 0; j < n; ++j) { |
| A1[i * n + j] = 0.0f; |
| for (int k = 0; k < m; ++k) { |
| A1[i * n + j] += A0[i * m + k] * U[j * m + k]; |
| } |
| } |
| } |
|
|
| |
| printf("A1:\n"); |
| for (int i = 0; i < n; ++i) { |
| printf("col %d : ", i); |
| for (int j = 0; j < n; ++j) { |
| printf("%9.5f ", A1[i * n + j]); |
| } |
| printf("\n"); |
| } |
| printf("\n"); |
|
|
| return 0; |
| } |
|
|