Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <assert.h>
- int* summation(const int* A, const int* B, int n) {
- int* C = malloc(n * n * sizeof(*C));
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n; j++) {
- C[i * n + j] = A[i * n + j] + B[i * n + j];
- }
- }
- return C;
- }
- int* subtraction(const int* A, const int* B, int n) {
- int* C = malloc(n * n * sizeof(*C));
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n; j++) {
- C[i * n + j] = A[i * n + j] - B[i * n + j];
- }
- }
- return C;
- }
- int* multiply(const int* A, const int* B, int n) {
- int* C = malloc(n * n * sizeof(*C));
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n; j++) {
- C[i * n + j] = 0;
- for (int k = 0; k < n; k++) {
- C[i * n + j] += A[i * n + k] * B[k * n + j];
- }
- }
- }
- return C;
- }
- void splitMatrix(const int* A, int* A11, int* A12, int* A21, int* A22, int n) {
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n; j++) {
- A11[i * n + j] = A[i * n + j];
- A12[i * n + j] = A[i * n + j + n];
- A21[i * n + j] = A[(i + n) * n + j];
- A22[i * n + j] = A[(i + n) * n + j + n];
- }
- }
- }
- int* mergeMatrix(const int* A11, const int* A12, const int* A21, const int* A22, int n) {
- int* A = malloc((n << 1) * (n << 1) * sizeof(*A));
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n; j++) {
- A[i * n + j] = A11[i * n + j];
- A[i * n + j + n] = A12[i * n + j];
- A[(i + n) * n + j] = A21[i * n + j];
- A[(i + n) * n + j + n] = A22[i * n + j];
- }
- }
- return A;
- }
- int* strassenMultiply(int* A, int* B, int n) {
- if (n <= 64) {
- return multiply(A, B, n);
- }
- n >>= 1;
- int* A11 = malloc(n * n * sizeof(*A11));
- int* A12 = malloc(n * n * sizeof(*A12));
- int* A21 = malloc(n * n * sizeof(*A21));
- int* A22 = malloc(n * n * sizeof(*A22));
- int* B11 = malloc(n * n * sizeof(*B11));
- int* B12 = malloc(n * n * sizeof(*B12));
- int* B21 = malloc(n * n * sizeof(*B21));
- int* B22 = malloc(n * n * sizeof(*B22));
- splitMatrix(A, A11, A12, A21, A22, n);
- splitMatrix(B, B11, B12, B21, B22, n);
- int* P1 = strassenMultiply(summation(A11, A22, n), summation(B11, B22, n), n);
- int* P2 = strassenMultiply(summation(A21, A22, n), B11, n);
- int* P3 = strassenMultiply(A11, subtraction(B12, B22, n), n);
- int* P4 = strassenMultiply(A22, subtraction(B21, B11, n), n);
- int* P5 = strassenMultiply(summation(A11, A12, n), B22, n);
- int* P6 = strassenMultiply(subtraction(A21, A11, n), summation(B11, B12, n), n);
- int* P7 = strassenMultiply(subtraction(A12, A22, n), summation(B21, B22, n), n);
- int* C11 = summation(summation(P1, P4, n), subtraction(P7, P5, n), n);
- int* C12 = summation(P3, P5, n);
- int* C21 = summation(P2, P4, n);
- int* C22 = summation(subtraction(P1, P2, n), summation(P3, P6, n), n);
- return mergeMatrix(C11, C12, C21, C22, n);
- }
- int main() {
- int n;
- scanf("%i", &n);
- assert(__builtin_popcount(n) == 1);
- int* A = malloc(n * n * sizeof(*A));
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < n; ++j) {
- scanf("%i", &A[i * n + j]);
- }
- }
- int* B = malloc(n * n * sizeof(*B));
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < n; ++j) {
- scanf("%i", &B[i * n + j]);
- }
- }
- int* C = strassenMultiply(A, B, n);
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n; j++) {
- printf("%i ", C[i * n + j]);
- }
- putchar('\n');
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment