Guest User

Untitled

a guest
Nov 18th, 2022
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.89 KB | None | 0 0
  1. #include <iostream>
  2. #include <xmmintrin.h>
  3. #include <cstdlib>
  4. #include <cfloat>
  5. #include <random>
  6.  
  7. using namespace std;
  8. const inline size_t M = 1000;
  9. const inline size_t N = 4;
  10.  
  11. void CopyMatrix(const float* from, float* to) {
  12.     for (size_t i = 0; i < N; i++) {
  13.         for (size_t j = 0; j < N; j++) {
  14.             to[i * N + j] = from[i * N + j];
  15.         }
  16.     }
  17.  
  18. }
  19.  
  20. void SumMatrix(const float *M1, const float *M2, float *result) {
  21.     for (size_t i = 0; i < N; i++) {
  22.         for (size_t j = 0; j < N; j++) {
  23.             result[i * N + j] = M1[i * N + j] + M2[i * N + j];
  24.         }
  25.     }
  26. }
  27.  
  28. void showMatrix(const float *matrix) {
  29.     size_t i, j;
  30.     for (i = 0; i < N; ++i) {
  31.         for (j = 0; j < N; ++j) {
  32.             cout << matrix[i * N + j] << " ";
  33.         }
  34.         cout << endl;
  35.     }
  36.     cout << "\n\n\n";
  37. }
  38.  
  39. inline float generateRandomInRange(float a, float b) {
  40.     random_device rd;
  41.     uniform_real_distribution gen(a, b);
  42.     return gen(rd);
  43. }
  44.  
  45. float *GenerateMatrixI() {
  46.     auto *I = new float[N * N];
  47.     for (size_t i = 0; i < N; i++) {
  48.         for (size_t j = 0; j < N; j++) {
  49.             if (i == j) I[i * N + j] = 1.0;
  50.             else I[i * N + j] = 0.0;
  51.         }
  52.     }
  53.     return I;
  54. }
  55.  
  56. float *GenerateMatrix() {
  57.     auto *A = new float[N * N];
  58.     for (size_t i = 0; i < N; i++) {
  59.         for (size_t j = 0; j < N; j++) {
  60.             A[i * N + j] = generateRandomInRange(1, 100);
  61.         }
  62.     }
  63.     A[0] = 1;
  64.     A[1] = 2;
  65.     A[2] = 3;
  66.     A[3] = 4;
  67.     A[4] = 2;
  68.     A[5] = 3;
  69.     A[6] = 1;
  70.     A[7] = 2;
  71.     A[8] = 1;
  72.     A[9] = 1;
  73.     A[10] = 1;
  74.     A[11] = -1;
  75.     A[12] = 1;
  76.     A[13] = 0;
  77.     A[14] = -2;
  78.     A[15] = -6;
  79.     return A;
  80. }
  81.  
  82. void TransposeMatrix(float *B, const float *A) {
  83.     for (size_t i = 0; i < N; i++)
  84.         for (size_t j = 0; j < N; j++) {
  85.             B[i * N + j] = A[j * N + i];
  86.         }
  87. }
  88.  
  89. float MaxLineCount(const float *matrix) {
  90.     float maximum = FLT_MIN;
  91.     for (size_t i = 0; i < N; i++) {
  92.         float temp = 0;
  93.  
  94.         for (size_t j = 0; j < N; j++) {
  95.             temp += matrix[i * N + j];
  96.         }
  97.  
  98.         if (temp > maximum) {
  99.             maximum = temp;
  100.         }
  101.     }
  102.     return maximum;
  103. }
  104.  
  105. float *GenerateMatrixB(float *A) {
  106.     auto *B = new float[N * N];
  107.     auto *transposedA = new float[N * N];
  108.     TransposeMatrix(transposedA, A);
  109.     float maxRowCount = MaxLineCount(A);
  110.     float maxColumnCount = MaxLineCount(transposedA);
  111.     float divider = 1 / (maxRowCount * maxColumnCount);
  112.     for (size_t i = 0; i < N; i++) {
  113.         for (size_t j = 0; j < N; j++) {
  114.             B[i * N + j] = transposedA[i * N + j] * divider;
  115.         }
  116.     }
  117.     delete[] transposedA;
  118.     return B;
  119. }
  120.  
  121. float* MultiplyMatrices(const float* matrix_1, const float* matrix_2)
  122. {
  123.     __m128 vector_2;//переменная для хранения значения второй матрицы
  124.     __m128 result_vector;//переменная для записи итоговой марицы
  125.     auto* result_matrix = (float*)_mm_malloc(N * N * sizeof(float), 16);//выделение памяти с выравниванием
  126.     for (int i = 0; i < N; ++i) {
  127.         for (int j = 0; j < N; ++j) {
  128.             __m128 element_vector = _mm_set1_ps(matrix_1[i * N + j]);//4 позиции в одно значение
  129.             for (int k = 0; k < N; k += 4) {
  130.                 vector_2 = _mm_load_ps(&matrix_2[j * N + k]);//4 значение по адресу
  131.                 result_vector = _mm_load_ps(&result_matrix[i * N + k]);
  132.                 result_vector = _mm_add_ps(result_vector, _mm_mul_ps(element_vector, vector_2));
  133.                 _mm_store_ps(&result_matrix[i * N + k], result_vector);
  134.             }
  135.         }
  136.     }
  137.     return result_matrix;
  138. }
  139.  
  140.  
  141. void SubtractMatrix(const float *I, const float *multed, float *R) {
  142.     for (size_t i = 0; i < N; i++)
  143.         for (size_t j = 0; j < N; j++)
  144.             R[i * N + j] = I[i * N + j] - multed[i * N + j];
  145. }
  146.  
  147. float *GenerateMatrixR(const float *A, float *I, const float *B) {
  148.     auto *R = new float[N * N];
  149.     auto *multed = MultiplyMatrices(B, A);
  150.     // R - BA
  151.     SubtractMatrix(I, multed, R);
  152.     delete[] multed;
  153.     return R;
  154. }
  155.  
  156. float *GetInversedMatrix(float *A) {
  157.     float *I = GenerateMatrixI();
  158.     auto *copyI = new float[N*N];
  159.     CopyMatrix(I, copyI);
  160.  
  161.     float *B = GenerateMatrixB(A);
  162.     std::cout << "B matrix" << std::endl;
  163.     showMatrix(B);
  164.  
  165.     float *R = GenerateMatrixR(A, copyI, B);
  166.     std::cout << "R matrix" << std::endl;
  167.     showMatrix(R);
  168.  
  169.  
  170.     float *Rn = R;
  171.     float *t;
  172.  
  173.     SumMatrix(I, Rn, I);
  174.     std::cout << "I matrix" << std::endl;
  175.     showMatrix(I);
  176.     for (size_t i = 0; i < M; i++) {
  177.         t = MultiplyMatrices(Rn, R);
  178.         std::cout << "T matrix " << i << " " << std::endl;
  179.         showMatrix(t);
  180.         if (i != 0) delete[] Rn;
  181.         Rn = t;
  182.         SumMatrix(I, Rn, I);
  183.         std::cout << "I matrix" << std::endl;
  184.         showMatrix(I);
  185.     }
  186.  
  187.  
  188.     auto new_I = MultiplyMatrices(I, B);
  189.  
  190.     delete[] I;
  191.     delete[] B;
  192.     delete[] R;
  193.     delete[] t;
  194.     delete [] copyI;
  195.     return new_I;
  196. }
  197.  
  198. int main() {
  199.     float *A = GenerateMatrix();
  200.     float *InversedA = GetInversedMatrix(A);
  201.     std::cout << "Matrix A" << std::endl;
  202.     showMatrix(A);
  203.  
  204.     std::cout << "Inversed Matrix" << std::endl;
  205.     showMatrix(InversedA);
  206.  
  207.     std::cout << "A*A^-1" << std::endl;
  208.     showMatrix(MultiplyMatrices(A,InversedA));
  209.  
  210.     delete[] A;
  211.     delete[] InversedA;
  212.     return 0;
  213. }
Add Comment
Please, Sign In to add comment