|
|
|
|
|
#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; |
|
} |
|
|