Strassen Vinograde Algorithm
I have written an implementation of the Strassen Vinograde Algorithm, but it's running slowly because of recursive creation of static arrays. I know that dynamic arrays would solve this problem, but I'm not allow to use them. So the main idea of this version of Strassen: We use corner elements of each square instead of copying every sub-square. I think something like this we should apply for the arrays that I create recursively.
In general, the main problem is that the algorithm is several times slower than usual even at larger values of n.
#include "pch.h"
#include<iostream>
#include<cstdio>
#include<conio.h>
#include<cstdlib>
#include<cmath>
#include<ctime>
#pragma comment(linker, "/STACK:5813242100")
using namespace std;
const int sizs = 256;
void vivod(int matrix[256], int n);
void Matrix_Add(int a[256], int b[256], int c[256], int n, int x1, int y1, int x2, int y2);
void Matrix_Sub(int a[256], int b[256], int c[256], int n, int x1, int y1, int x2, int y2);
void Matrix_Multiply(int a[256], int b[256], int c[256], int x1, int y1, int x2, int y2, int n);
void strassen(int a[256], int b[256], int c[256], int m, int n, int x1, int y1, int x2, int y2);
void Naive_Multiply(int a[256], int b[256], int c[256], int n);
int main()
{
setlocale(LC_ALL, "Russian");
int n;
cout << "Enter the N:";
cin >> n;
const int m = 256;
int A[m][m];
int B[m][m];
int C[m][m];
int k[m][m];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
A[i][j] = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
B[i][j] = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
A[i][j] = rand() % 10;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
B[i][j] = rand() % 10;
cout << "First Matrix:" << endl;
//vivod(A, n);
cout << "Second Matrix:" << endl;
//vivod(B, n);
int begin = clock();
//for (int i =0; i < 100; i++)
Naive_Multiply(A, B, k, n);
int end = clock();
cout << "Naive Multiply tacts: " << end - begin << endl;
//vivod(k, n);
int begin2 = clock();
//for (int i = 0; i < 100; i++)
strassen(A, B, C, n, n, 0, 0, 0, 0);
int end2 = clock();
cout << "Shtrassen tacts: " << end2 - begin2 << endl;
//vivod(C, n);
system("pause");
return 0;
}
void strassen(int a[256], int b[256], int c[256], int m, int n, int x1, int y1, int x2, int y2) {
m = n / 2;
if (m != 1)
{
int s1[sizs][sizs];
int s2[sizs][sizs];
int s3[sizs][sizs];
int s4[sizs][sizs];
int s5[sizs][sizs];
int s6[sizs][sizs];
int s7[sizs][sizs];
int s8[sizs][sizs];
int m1[sizs][sizs];
int m2[sizs][sizs];
int m3[sizs][sizs];
int m4[sizs][sizs];
int m5[sizs][sizs];
int m6[sizs][sizs];
int m7[sizs][sizs];
int t1[sizs][sizs];
int t2[sizs][sizs];
int c11[sizs][sizs];
int c12[sizs][sizs];
int c21[sizs][sizs];
int c22[sizs][sizs];
Matrix_Add(a, a, s1, m, x1 + m, y1, x1 + m, y1 + m);
Matrix_Sub(s1, a, s2, m, 0, 0, x1, y1);
Matrix_Sub(a, a, s3, m, x1, y1, x1 + m, y1);
Matrix_Sub(a, s2, s4, m, x1, y1 + m, 0, 0);
Matrix_Sub(b, b, s5, m, x2, y2 + m, x2, y2);
Matrix_Sub(b, s5, s6, m, x2 + m, y2 + m, 0, 0);
Matrix_Sub(b, b, s7, m, x2 + m, y2 + m, x2, y2 + m);
Matrix_Sub(s6, b, s8, m, 0, 0, x2 + m, y2);
strassen(s2, s6, m1, m, m, 0, 0, 0, 0);
strassen(a, b, m2, m, m, x1, y1, x2, y2);
strassen(a, b, m3, m, m, x1, y1 + m, x2 + m, y2);
strassen(s3, s7, m4, m, m, 0, 0, 0, 0);
strassen(s1, s5, m5, m, m, 0, 0, 0, 0);
strassen(s4, b, m6, m, m, 0, 0, x2 + m, y2 + m);
strassen(a, s8, m7, m, m, x1 + m, y1 + m, 0, 0);
Matrix_Add(m1, m2, t1, m, 0, 0, 0, 0);
Matrix_Add(t1, m4, t2, m, 0, 0, 0, 0);
Matrix_Add(m2, m3, c11, m, 0, 0, 0, 0);
Matrix_Sub(t2, m7, c21, m, 0, 0, 0, 0);
Matrix_Add(t1, m5, c12, m, 0, 0, 0, 0);
Matrix_Add(c12, m6, c12, m, 0, 0, 0, 0);
Matrix_Add(t2, m5, c22, m, 0, 0, 0, 0);
for (int i = 0; i < n / 2; i++)
{
for (int j = 0; j < n / 2; j++)
{
c[i + n - 2 * m][j + n - 2 * m] = c11[i][j];
c[i + n - 2 * m][j + n - m] = c12[i][j];
c[i + n - m][j + n - 2 * m] = c21[i][j];
c[i + n - m][j + n - m] = c22[i][j];
}
}
}
else
{
Matrix_Multiply(a, b, c, x1, y1, x2, y2, n);
}
}
void vivod(int matrix[256], int n)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout << matrix[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
void Matrix_Add(int a[256], int b[256], int c[256], int n, int x1, int y1, int x2, int y2)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = a[i + x1][j + y1] + b[i + x2][j + y2];
}
}
}
void Matrix_Sub(int a[256], int b[256], int c[256], int n, int x1, int y1, int x2, int y2)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = a[i + x1][j + y1] - b[i + x2][j + y2];
}
}
}
void Matrix_Multiply(int a[256], int b[256], int c[256], int x1, int y1, int x2, int y2, int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = 0;
for (int t = 0; t < n; t++) {
c[i][j] = c[i][j] + a[x1 + i][y1 + t] * b[x2 + t][y2 + j];
}
}
}
}
void Naive_Multiply(int a[256], int b[256], int c[256], int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = 0;
for (int t = 0; t < n; t++) {
c[i][j] = c[i][j] + a[i][t] * b[t][j];
}
}
}
}
It probably may not even start, because of large amount of arrays, but i have launched it and here is the tests:
With N = 128 and 256 naive multiplication takes nearly 10 seconds, when at the same time I'm waiting for Strassen for ~1-5 minutes.
c++ algorithm matrix
New contributor
add a comment |
I have written an implementation of the Strassen Vinograde Algorithm, but it's running slowly because of recursive creation of static arrays. I know that dynamic arrays would solve this problem, but I'm not allow to use them. So the main idea of this version of Strassen: We use corner elements of each square instead of copying every sub-square. I think something like this we should apply for the arrays that I create recursively.
In general, the main problem is that the algorithm is several times slower than usual even at larger values of n.
#include "pch.h"
#include<iostream>
#include<cstdio>
#include<conio.h>
#include<cstdlib>
#include<cmath>
#include<ctime>
#pragma comment(linker, "/STACK:5813242100")
using namespace std;
const int sizs = 256;
void vivod(int matrix[256], int n);
void Matrix_Add(int a[256], int b[256], int c[256], int n, int x1, int y1, int x2, int y2);
void Matrix_Sub(int a[256], int b[256], int c[256], int n, int x1, int y1, int x2, int y2);
void Matrix_Multiply(int a[256], int b[256], int c[256], int x1, int y1, int x2, int y2, int n);
void strassen(int a[256], int b[256], int c[256], int m, int n, int x1, int y1, int x2, int y2);
void Naive_Multiply(int a[256], int b[256], int c[256], int n);
int main()
{
setlocale(LC_ALL, "Russian");
int n;
cout << "Enter the N:";
cin >> n;
const int m = 256;
int A[m][m];
int B[m][m];
int C[m][m];
int k[m][m];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
A[i][j] = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
B[i][j] = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
A[i][j] = rand() % 10;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
B[i][j] = rand() % 10;
cout << "First Matrix:" << endl;
//vivod(A, n);
cout << "Second Matrix:" << endl;
//vivod(B, n);
int begin = clock();
//for (int i =0; i < 100; i++)
Naive_Multiply(A, B, k, n);
int end = clock();
cout << "Naive Multiply tacts: " << end - begin << endl;
//vivod(k, n);
int begin2 = clock();
//for (int i = 0; i < 100; i++)
strassen(A, B, C, n, n, 0, 0, 0, 0);
int end2 = clock();
cout << "Shtrassen tacts: " << end2 - begin2 << endl;
//vivod(C, n);
system("pause");
return 0;
}
void strassen(int a[256], int b[256], int c[256], int m, int n, int x1, int y1, int x2, int y2) {
m = n / 2;
if (m != 1)
{
int s1[sizs][sizs];
int s2[sizs][sizs];
int s3[sizs][sizs];
int s4[sizs][sizs];
int s5[sizs][sizs];
int s6[sizs][sizs];
int s7[sizs][sizs];
int s8[sizs][sizs];
int m1[sizs][sizs];
int m2[sizs][sizs];
int m3[sizs][sizs];
int m4[sizs][sizs];
int m5[sizs][sizs];
int m6[sizs][sizs];
int m7[sizs][sizs];
int t1[sizs][sizs];
int t2[sizs][sizs];
int c11[sizs][sizs];
int c12[sizs][sizs];
int c21[sizs][sizs];
int c22[sizs][sizs];
Matrix_Add(a, a, s1, m, x1 + m, y1, x1 + m, y1 + m);
Matrix_Sub(s1, a, s2, m, 0, 0, x1, y1);
Matrix_Sub(a, a, s3, m, x1, y1, x1 + m, y1);
Matrix_Sub(a, s2, s4, m, x1, y1 + m, 0, 0);
Matrix_Sub(b, b, s5, m, x2, y2 + m, x2, y2);
Matrix_Sub(b, s5, s6, m, x2 + m, y2 + m, 0, 0);
Matrix_Sub(b, b, s7, m, x2 + m, y2 + m, x2, y2 + m);
Matrix_Sub(s6, b, s8, m, 0, 0, x2 + m, y2);
strassen(s2, s6, m1, m, m, 0, 0, 0, 0);
strassen(a, b, m2, m, m, x1, y1, x2, y2);
strassen(a, b, m3, m, m, x1, y1 + m, x2 + m, y2);
strassen(s3, s7, m4, m, m, 0, 0, 0, 0);
strassen(s1, s5, m5, m, m, 0, 0, 0, 0);
strassen(s4, b, m6, m, m, 0, 0, x2 + m, y2 + m);
strassen(a, s8, m7, m, m, x1 + m, y1 + m, 0, 0);
Matrix_Add(m1, m2, t1, m, 0, 0, 0, 0);
Matrix_Add(t1, m4, t2, m, 0, 0, 0, 0);
Matrix_Add(m2, m3, c11, m, 0, 0, 0, 0);
Matrix_Sub(t2, m7, c21, m, 0, 0, 0, 0);
Matrix_Add(t1, m5, c12, m, 0, 0, 0, 0);
Matrix_Add(c12, m6, c12, m, 0, 0, 0, 0);
Matrix_Add(t2, m5, c22, m, 0, 0, 0, 0);
for (int i = 0; i < n / 2; i++)
{
for (int j = 0; j < n / 2; j++)
{
c[i + n - 2 * m][j + n - 2 * m] = c11[i][j];
c[i + n - 2 * m][j + n - m] = c12[i][j];
c[i + n - m][j + n - 2 * m] = c21[i][j];
c[i + n - m][j + n - m] = c22[i][j];
}
}
}
else
{
Matrix_Multiply(a, b, c, x1, y1, x2, y2, n);
}
}
void vivod(int matrix[256], int n)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout << matrix[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
void Matrix_Add(int a[256], int b[256], int c[256], int n, int x1, int y1, int x2, int y2)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = a[i + x1][j + y1] + b[i + x2][j + y2];
}
}
}
void Matrix_Sub(int a[256], int b[256], int c[256], int n, int x1, int y1, int x2, int y2)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = a[i + x1][j + y1] - b[i + x2][j + y2];
}
}
}
void Matrix_Multiply(int a[256], int b[256], int c[256], int x1, int y1, int x2, int y2, int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = 0;
for (int t = 0; t < n; t++) {
c[i][j] = c[i][j] + a[x1 + i][y1 + t] * b[x2 + t][y2 + j];
}
}
}
}
void Naive_Multiply(int a[256], int b[256], int c[256], int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = 0;
for (int t = 0; t < n; t++) {
c[i][j] = c[i][j] + a[i][t] * b[t][j];
}
}
}
}
It probably may not even start, because of large amount of arrays, but i have launched it and here is the tests:
With N = 128 and 256 naive multiplication takes nearly 10 seconds, when at the same time I'm waiting for Strassen for ~1-5 minutes.
c++ algorithm matrix
New contributor
1
Brainstorming here, what do you mean no dynamic arrays? You're probably going to have to pre-declare storage for all the temporaries, using depth as well as row,col boundaries, so the recursive calls can share space in each NxN temporary. It might be ugly, but it will avoid declaring a bunch of extra MAX by MAX temporary arrays for tiny subproblems.
– Kenny Ostrom
Dec 16 at 18:24
Maybe we need source storage, but their number for example for 256x256 matrices will be very large.
– Emik
Dec 16 at 18:37
And I do not fully understand your idea.
– Emik
Dec 16 at 18:43
In addition, we can create dynamic arrays in main function, but it's not allowed to do it recursively.
– Emik
Dec 16 at 19:29
For reference, original question: stackoverflow.com/questions/53802871
– chtz
yesterday
add a comment |
I have written an implementation of the Strassen Vinograde Algorithm, but it's running slowly because of recursive creation of static arrays. I know that dynamic arrays would solve this problem, but I'm not allow to use them. So the main idea of this version of Strassen: We use corner elements of each square instead of copying every sub-square. I think something like this we should apply for the arrays that I create recursively.
In general, the main problem is that the algorithm is several times slower than usual even at larger values of n.
#include "pch.h"
#include<iostream>
#include<cstdio>
#include<conio.h>
#include<cstdlib>
#include<cmath>
#include<ctime>
#pragma comment(linker, "/STACK:5813242100")
using namespace std;
const int sizs = 256;
void vivod(int matrix[256], int n);
void Matrix_Add(int a[256], int b[256], int c[256], int n, int x1, int y1, int x2, int y2);
void Matrix_Sub(int a[256], int b[256], int c[256], int n, int x1, int y1, int x2, int y2);
void Matrix_Multiply(int a[256], int b[256], int c[256], int x1, int y1, int x2, int y2, int n);
void strassen(int a[256], int b[256], int c[256], int m, int n, int x1, int y1, int x2, int y2);
void Naive_Multiply(int a[256], int b[256], int c[256], int n);
int main()
{
setlocale(LC_ALL, "Russian");
int n;
cout << "Enter the N:";
cin >> n;
const int m = 256;
int A[m][m];
int B[m][m];
int C[m][m];
int k[m][m];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
A[i][j] = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
B[i][j] = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
A[i][j] = rand() % 10;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
B[i][j] = rand() % 10;
cout << "First Matrix:" << endl;
//vivod(A, n);
cout << "Second Matrix:" << endl;
//vivod(B, n);
int begin = clock();
//for (int i =0; i < 100; i++)
Naive_Multiply(A, B, k, n);
int end = clock();
cout << "Naive Multiply tacts: " << end - begin << endl;
//vivod(k, n);
int begin2 = clock();
//for (int i = 0; i < 100; i++)
strassen(A, B, C, n, n, 0, 0, 0, 0);
int end2 = clock();
cout << "Shtrassen tacts: " << end2 - begin2 << endl;
//vivod(C, n);
system("pause");
return 0;
}
void strassen(int a[256], int b[256], int c[256], int m, int n, int x1, int y1, int x2, int y2) {
m = n / 2;
if (m != 1)
{
int s1[sizs][sizs];
int s2[sizs][sizs];
int s3[sizs][sizs];
int s4[sizs][sizs];
int s5[sizs][sizs];
int s6[sizs][sizs];
int s7[sizs][sizs];
int s8[sizs][sizs];
int m1[sizs][sizs];
int m2[sizs][sizs];
int m3[sizs][sizs];
int m4[sizs][sizs];
int m5[sizs][sizs];
int m6[sizs][sizs];
int m7[sizs][sizs];
int t1[sizs][sizs];
int t2[sizs][sizs];
int c11[sizs][sizs];
int c12[sizs][sizs];
int c21[sizs][sizs];
int c22[sizs][sizs];
Matrix_Add(a, a, s1, m, x1 + m, y1, x1 + m, y1 + m);
Matrix_Sub(s1, a, s2, m, 0, 0, x1, y1);
Matrix_Sub(a, a, s3, m, x1, y1, x1 + m, y1);
Matrix_Sub(a, s2, s4, m, x1, y1 + m, 0, 0);
Matrix_Sub(b, b, s5, m, x2, y2 + m, x2, y2);
Matrix_Sub(b, s5, s6, m, x2 + m, y2 + m, 0, 0);
Matrix_Sub(b, b, s7, m, x2 + m, y2 + m, x2, y2 + m);
Matrix_Sub(s6, b, s8, m, 0, 0, x2 + m, y2);
strassen(s2, s6, m1, m, m, 0, 0, 0, 0);
strassen(a, b, m2, m, m, x1, y1, x2, y2);
strassen(a, b, m3, m, m, x1, y1 + m, x2 + m, y2);
strassen(s3, s7, m4, m, m, 0, 0, 0, 0);
strassen(s1, s5, m5, m, m, 0, 0, 0, 0);
strassen(s4, b, m6, m, m, 0, 0, x2 + m, y2 + m);
strassen(a, s8, m7, m, m, x1 + m, y1 + m, 0, 0);
Matrix_Add(m1, m2, t1, m, 0, 0, 0, 0);
Matrix_Add(t1, m4, t2, m, 0, 0, 0, 0);
Matrix_Add(m2, m3, c11, m, 0, 0, 0, 0);
Matrix_Sub(t2, m7, c21, m, 0, 0, 0, 0);
Matrix_Add(t1, m5, c12, m, 0, 0, 0, 0);
Matrix_Add(c12, m6, c12, m, 0, 0, 0, 0);
Matrix_Add(t2, m5, c22, m, 0, 0, 0, 0);
for (int i = 0; i < n / 2; i++)
{
for (int j = 0; j < n / 2; j++)
{
c[i + n - 2 * m][j + n - 2 * m] = c11[i][j];
c[i + n - 2 * m][j + n - m] = c12[i][j];
c[i + n - m][j + n - 2 * m] = c21[i][j];
c[i + n - m][j + n - m] = c22[i][j];
}
}
}
else
{
Matrix_Multiply(a, b, c, x1, y1, x2, y2, n);
}
}
void vivod(int matrix[256], int n)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout << matrix[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
void Matrix_Add(int a[256], int b[256], int c[256], int n, int x1, int y1, int x2, int y2)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = a[i + x1][j + y1] + b[i + x2][j + y2];
}
}
}
void Matrix_Sub(int a[256], int b[256], int c[256], int n, int x1, int y1, int x2, int y2)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = a[i + x1][j + y1] - b[i + x2][j + y2];
}
}
}
void Matrix_Multiply(int a[256], int b[256], int c[256], int x1, int y1, int x2, int y2, int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = 0;
for (int t = 0; t < n; t++) {
c[i][j] = c[i][j] + a[x1 + i][y1 + t] * b[x2 + t][y2 + j];
}
}
}
}
void Naive_Multiply(int a[256], int b[256], int c[256], int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = 0;
for (int t = 0; t < n; t++) {
c[i][j] = c[i][j] + a[i][t] * b[t][j];
}
}
}
}
It probably may not even start, because of large amount of arrays, but i have launched it and here is the tests:
With N = 128 and 256 naive multiplication takes nearly 10 seconds, when at the same time I'm waiting for Strassen for ~1-5 minutes.
c++ algorithm matrix
New contributor
I have written an implementation of the Strassen Vinograde Algorithm, but it's running slowly because of recursive creation of static arrays. I know that dynamic arrays would solve this problem, but I'm not allow to use them. So the main idea of this version of Strassen: We use corner elements of each square instead of copying every sub-square. I think something like this we should apply for the arrays that I create recursively.
In general, the main problem is that the algorithm is several times slower than usual even at larger values of n.
#include "pch.h"
#include<iostream>
#include<cstdio>
#include<conio.h>
#include<cstdlib>
#include<cmath>
#include<ctime>
#pragma comment(linker, "/STACK:5813242100")
using namespace std;
const int sizs = 256;
void vivod(int matrix[256], int n);
void Matrix_Add(int a[256], int b[256], int c[256], int n, int x1, int y1, int x2, int y2);
void Matrix_Sub(int a[256], int b[256], int c[256], int n, int x1, int y1, int x2, int y2);
void Matrix_Multiply(int a[256], int b[256], int c[256], int x1, int y1, int x2, int y2, int n);
void strassen(int a[256], int b[256], int c[256], int m, int n, int x1, int y1, int x2, int y2);
void Naive_Multiply(int a[256], int b[256], int c[256], int n);
int main()
{
setlocale(LC_ALL, "Russian");
int n;
cout << "Enter the N:";
cin >> n;
const int m = 256;
int A[m][m];
int B[m][m];
int C[m][m];
int k[m][m];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
A[i][j] = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
B[i][j] = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
A[i][j] = rand() % 10;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
B[i][j] = rand() % 10;
cout << "First Matrix:" << endl;
//vivod(A, n);
cout << "Second Matrix:" << endl;
//vivod(B, n);
int begin = clock();
//for (int i =0; i < 100; i++)
Naive_Multiply(A, B, k, n);
int end = clock();
cout << "Naive Multiply tacts: " << end - begin << endl;
//vivod(k, n);
int begin2 = clock();
//for (int i = 0; i < 100; i++)
strassen(A, B, C, n, n, 0, 0, 0, 0);
int end2 = clock();
cout << "Shtrassen tacts: " << end2 - begin2 << endl;
//vivod(C, n);
system("pause");
return 0;
}
void strassen(int a[256], int b[256], int c[256], int m, int n, int x1, int y1, int x2, int y2) {
m = n / 2;
if (m != 1)
{
int s1[sizs][sizs];
int s2[sizs][sizs];
int s3[sizs][sizs];
int s4[sizs][sizs];
int s5[sizs][sizs];
int s6[sizs][sizs];
int s7[sizs][sizs];
int s8[sizs][sizs];
int m1[sizs][sizs];
int m2[sizs][sizs];
int m3[sizs][sizs];
int m4[sizs][sizs];
int m5[sizs][sizs];
int m6[sizs][sizs];
int m7[sizs][sizs];
int t1[sizs][sizs];
int t2[sizs][sizs];
int c11[sizs][sizs];
int c12[sizs][sizs];
int c21[sizs][sizs];
int c22[sizs][sizs];
Matrix_Add(a, a, s1, m, x1 + m, y1, x1 + m, y1 + m);
Matrix_Sub(s1, a, s2, m, 0, 0, x1, y1);
Matrix_Sub(a, a, s3, m, x1, y1, x1 + m, y1);
Matrix_Sub(a, s2, s4, m, x1, y1 + m, 0, 0);
Matrix_Sub(b, b, s5, m, x2, y2 + m, x2, y2);
Matrix_Sub(b, s5, s6, m, x2 + m, y2 + m, 0, 0);
Matrix_Sub(b, b, s7, m, x2 + m, y2 + m, x2, y2 + m);
Matrix_Sub(s6, b, s8, m, 0, 0, x2 + m, y2);
strassen(s2, s6, m1, m, m, 0, 0, 0, 0);
strassen(a, b, m2, m, m, x1, y1, x2, y2);
strassen(a, b, m3, m, m, x1, y1 + m, x2 + m, y2);
strassen(s3, s7, m4, m, m, 0, 0, 0, 0);
strassen(s1, s5, m5, m, m, 0, 0, 0, 0);
strassen(s4, b, m6, m, m, 0, 0, x2 + m, y2 + m);
strassen(a, s8, m7, m, m, x1 + m, y1 + m, 0, 0);
Matrix_Add(m1, m2, t1, m, 0, 0, 0, 0);
Matrix_Add(t1, m4, t2, m, 0, 0, 0, 0);
Matrix_Add(m2, m3, c11, m, 0, 0, 0, 0);
Matrix_Sub(t2, m7, c21, m, 0, 0, 0, 0);
Matrix_Add(t1, m5, c12, m, 0, 0, 0, 0);
Matrix_Add(c12, m6, c12, m, 0, 0, 0, 0);
Matrix_Add(t2, m5, c22, m, 0, 0, 0, 0);
for (int i = 0; i < n / 2; i++)
{
for (int j = 0; j < n / 2; j++)
{
c[i + n - 2 * m][j + n - 2 * m] = c11[i][j];
c[i + n - 2 * m][j + n - m] = c12[i][j];
c[i + n - m][j + n - 2 * m] = c21[i][j];
c[i + n - m][j + n - m] = c22[i][j];
}
}
}
else
{
Matrix_Multiply(a, b, c, x1, y1, x2, y2, n);
}
}
void vivod(int matrix[256], int n)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout << matrix[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
void Matrix_Add(int a[256], int b[256], int c[256], int n, int x1, int y1, int x2, int y2)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = a[i + x1][j + y1] + b[i + x2][j + y2];
}
}
}
void Matrix_Sub(int a[256], int b[256], int c[256], int n, int x1, int y1, int x2, int y2)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = a[i + x1][j + y1] - b[i + x2][j + y2];
}
}
}
void Matrix_Multiply(int a[256], int b[256], int c[256], int x1, int y1, int x2, int y2, int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = 0;
for (int t = 0; t < n; t++) {
c[i][j] = c[i][j] + a[x1 + i][y1 + t] * b[x2 + t][y2 + j];
}
}
}
}
void Naive_Multiply(int a[256], int b[256], int c[256], int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = 0;
for (int t = 0; t < n; t++) {
c[i][j] = c[i][j] + a[i][t] * b[t][j];
}
}
}
}
It probably may not even start, because of large amount of arrays, but i have launched it and here is the tests:
With N = 128 and 256 naive multiplication takes nearly 10 seconds, when at the same time I'm waiting for Strassen for ~1-5 minutes.
c++ algorithm matrix
c++ algorithm matrix
New contributor
New contributor
edited Dec 16 at 17:38
Reinderien
2,251617
2,251617
New contributor
asked Dec 16 at 16:57
Emik
162
162
New contributor
New contributor
1
Brainstorming here, what do you mean no dynamic arrays? You're probably going to have to pre-declare storage for all the temporaries, using depth as well as row,col boundaries, so the recursive calls can share space in each NxN temporary. It might be ugly, but it will avoid declaring a bunch of extra MAX by MAX temporary arrays for tiny subproblems.
– Kenny Ostrom
Dec 16 at 18:24
Maybe we need source storage, but their number for example for 256x256 matrices will be very large.
– Emik
Dec 16 at 18:37
And I do not fully understand your idea.
– Emik
Dec 16 at 18:43
In addition, we can create dynamic arrays in main function, but it's not allowed to do it recursively.
– Emik
Dec 16 at 19:29
For reference, original question: stackoverflow.com/questions/53802871
– chtz
yesterday
add a comment |
1
Brainstorming here, what do you mean no dynamic arrays? You're probably going to have to pre-declare storage for all the temporaries, using depth as well as row,col boundaries, so the recursive calls can share space in each NxN temporary. It might be ugly, but it will avoid declaring a bunch of extra MAX by MAX temporary arrays for tiny subproblems.
– Kenny Ostrom
Dec 16 at 18:24
Maybe we need source storage, but their number for example for 256x256 matrices will be very large.
– Emik
Dec 16 at 18:37
And I do not fully understand your idea.
– Emik
Dec 16 at 18:43
In addition, we can create dynamic arrays in main function, but it's not allowed to do it recursively.
– Emik
Dec 16 at 19:29
For reference, original question: stackoverflow.com/questions/53802871
– chtz
yesterday
1
1
Brainstorming here, what do you mean no dynamic arrays? You're probably going to have to pre-declare storage for all the temporaries, using depth as well as row,col boundaries, so the recursive calls can share space in each NxN temporary. It might be ugly, but it will avoid declaring a bunch of extra MAX by MAX temporary arrays for tiny subproblems.
– Kenny Ostrom
Dec 16 at 18:24
Brainstorming here, what do you mean no dynamic arrays? You're probably going to have to pre-declare storage for all the temporaries, using depth as well as row,col boundaries, so the recursive calls can share space in each NxN temporary. It might be ugly, but it will avoid declaring a bunch of extra MAX by MAX temporary arrays for tiny subproblems.
– Kenny Ostrom
Dec 16 at 18:24
Maybe we need source storage, but their number for example for 256x256 matrices will be very large.
– Emik
Dec 16 at 18:37
Maybe we need source storage, but their number for example for 256x256 matrices will be very large.
– Emik
Dec 16 at 18:37
And I do not fully understand your idea.
– Emik
Dec 16 at 18:43
And I do not fully understand your idea.
– Emik
Dec 16 at 18:43
In addition, we can create dynamic arrays in main function, but it's not allowed to do it recursively.
– Emik
Dec 16 at 19:29
In addition, we can create dynamic arrays in main function, but it's not allowed to do it recursively.
– Emik
Dec 16 at 19:29
For reference, original question: stackoverflow.com/questions/53802871
– chtz
yesterday
For reference, original question: stackoverflow.com/questions/53802871
– chtz
yesterday
add a comment |
1 Answer
1
active
oldest
votes
I am not really sure if this question is correctly tagged, as what you wrote seems a lot like plain C-Code. If you really need static storage, you can always just fall back to std::array
, which is more or less a wrapper around a plain C-style array.
So you should be able to replace int[256][256]
by std::array<std::array<int, 256>, 256>
. Note that in most times it is beneficial to have one array and use indexing to access the individual elements, but that is for another day.
Note that std::array
does not feature a constructor, so you would still have to manually fill it.
Since recently you can declare variables as constexpr
, which is a good replacement for your local variable m
.
Now regarding the actual code:
You should not use
using namespace std;
This is bad practice that will pollute the entire namespace needlessly. It is quite beneficial to get into the habit of writingstd::
whenever necessary.Your original loops in main all run the same length so justfill the elements once and dont interate so often
Regarding the respective functions you should be able to utilize quite a bit of functionality from the
algorithm
library.
First lets have a look at Naive_Multiply:
void Naive_Multiply(int a[256], int b[256], int c[256], int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = 0;
for (int t = 0; t < n; t++) {
c[i][j] = c[i][j] + a[i][t] * b[t][j];
}
}
}
}
Here you can use std::inner_product
constexpr int rowSize = 256;
using row = std::array<int, m>;
using mat = std::array<row , m>
mat Naive_Multiply(const mat& a, const mat& b)
{
mat c;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
auto multiplyRowElement = [j](const int a, const row& b) {
return a * b[j];
};
c[i][j] = std::inner_product(a[i].begin(), a[i].end(),
b.begin(), b.end(), 0,
std::plus<int>, multiplyRowElement);
}
}
return c;
}
Note that we also directly return the result of the operation rather than passing it as an inout parameter to the function, which is much cleaner.
It seems your otehr functions create access violations if any of the additional parameters is not equal to 0. In that case you iterate over the border of the array.
I am very grateful for your hints, but before using various functions, I must learn the principles of their work. So, that is why i'm not using it, i'm just learning the language. And what about the main problem? How to do the algorithm without recursive array creation?
– Emik
Dec 18 at 22:18
@Emik The C++-standard-library is part of the language (not part of the core language, but part of the C++ standard)
– chtz
yesterday
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Emik is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209772%2fstrassen-vinograde-algorithm%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I am not really sure if this question is correctly tagged, as what you wrote seems a lot like plain C-Code. If you really need static storage, you can always just fall back to std::array
, which is more or less a wrapper around a plain C-style array.
So you should be able to replace int[256][256]
by std::array<std::array<int, 256>, 256>
. Note that in most times it is beneficial to have one array and use indexing to access the individual elements, but that is for another day.
Note that std::array
does not feature a constructor, so you would still have to manually fill it.
Since recently you can declare variables as constexpr
, which is a good replacement for your local variable m
.
Now regarding the actual code:
You should not use
using namespace std;
This is bad practice that will pollute the entire namespace needlessly. It is quite beneficial to get into the habit of writingstd::
whenever necessary.Your original loops in main all run the same length so justfill the elements once and dont interate so often
Regarding the respective functions you should be able to utilize quite a bit of functionality from the
algorithm
library.
First lets have a look at Naive_Multiply:
void Naive_Multiply(int a[256], int b[256], int c[256], int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = 0;
for (int t = 0; t < n; t++) {
c[i][j] = c[i][j] + a[i][t] * b[t][j];
}
}
}
}
Here you can use std::inner_product
constexpr int rowSize = 256;
using row = std::array<int, m>;
using mat = std::array<row , m>
mat Naive_Multiply(const mat& a, const mat& b)
{
mat c;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
auto multiplyRowElement = [j](const int a, const row& b) {
return a * b[j];
};
c[i][j] = std::inner_product(a[i].begin(), a[i].end(),
b.begin(), b.end(), 0,
std::plus<int>, multiplyRowElement);
}
}
return c;
}
Note that we also directly return the result of the operation rather than passing it as an inout parameter to the function, which is much cleaner.
It seems your otehr functions create access violations if any of the additional parameters is not equal to 0. In that case you iterate over the border of the array.
I am very grateful for your hints, but before using various functions, I must learn the principles of their work. So, that is why i'm not using it, i'm just learning the language. And what about the main problem? How to do the algorithm without recursive array creation?
– Emik
Dec 18 at 22:18
@Emik The C++-standard-library is part of the language (not part of the core language, but part of the C++ standard)
– chtz
yesterday
add a comment |
I am not really sure if this question is correctly tagged, as what you wrote seems a lot like plain C-Code. If you really need static storage, you can always just fall back to std::array
, which is more or less a wrapper around a plain C-style array.
So you should be able to replace int[256][256]
by std::array<std::array<int, 256>, 256>
. Note that in most times it is beneficial to have one array and use indexing to access the individual elements, but that is for another day.
Note that std::array
does not feature a constructor, so you would still have to manually fill it.
Since recently you can declare variables as constexpr
, which is a good replacement for your local variable m
.
Now regarding the actual code:
You should not use
using namespace std;
This is bad practice that will pollute the entire namespace needlessly. It is quite beneficial to get into the habit of writingstd::
whenever necessary.Your original loops in main all run the same length so justfill the elements once and dont interate so often
Regarding the respective functions you should be able to utilize quite a bit of functionality from the
algorithm
library.
First lets have a look at Naive_Multiply:
void Naive_Multiply(int a[256], int b[256], int c[256], int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = 0;
for (int t = 0; t < n; t++) {
c[i][j] = c[i][j] + a[i][t] * b[t][j];
}
}
}
}
Here you can use std::inner_product
constexpr int rowSize = 256;
using row = std::array<int, m>;
using mat = std::array<row , m>
mat Naive_Multiply(const mat& a, const mat& b)
{
mat c;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
auto multiplyRowElement = [j](const int a, const row& b) {
return a * b[j];
};
c[i][j] = std::inner_product(a[i].begin(), a[i].end(),
b.begin(), b.end(), 0,
std::plus<int>, multiplyRowElement);
}
}
return c;
}
Note that we also directly return the result of the operation rather than passing it as an inout parameter to the function, which is much cleaner.
It seems your otehr functions create access violations if any of the additional parameters is not equal to 0. In that case you iterate over the border of the array.
I am very grateful for your hints, but before using various functions, I must learn the principles of their work. So, that is why i'm not using it, i'm just learning the language. And what about the main problem? How to do the algorithm without recursive array creation?
– Emik
Dec 18 at 22:18
@Emik The C++-standard-library is part of the language (not part of the core language, but part of the C++ standard)
– chtz
yesterday
add a comment |
I am not really sure if this question is correctly tagged, as what you wrote seems a lot like plain C-Code. If you really need static storage, you can always just fall back to std::array
, which is more or less a wrapper around a plain C-style array.
So you should be able to replace int[256][256]
by std::array<std::array<int, 256>, 256>
. Note that in most times it is beneficial to have one array and use indexing to access the individual elements, but that is for another day.
Note that std::array
does not feature a constructor, so you would still have to manually fill it.
Since recently you can declare variables as constexpr
, which is a good replacement for your local variable m
.
Now regarding the actual code:
You should not use
using namespace std;
This is bad practice that will pollute the entire namespace needlessly. It is quite beneficial to get into the habit of writingstd::
whenever necessary.Your original loops in main all run the same length so justfill the elements once and dont interate so often
Regarding the respective functions you should be able to utilize quite a bit of functionality from the
algorithm
library.
First lets have a look at Naive_Multiply:
void Naive_Multiply(int a[256], int b[256], int c[256], int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = 0;
for (int t = 0; t < n; t++) {
c[i][j] = c[i][j] + a[i][t] * b[t][j];
}
}
}
}
Here you can use std::inner_product
constexpr int rowSize = 256;
using row = std::array<int, m>;
using mat = std::array<row , m>
mat Naive_Multiply(const mat& a, const mat& b)
{
mat c;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
auto multiplyRowElement = [j](const int a, const row& b) {
return a * b[j];
};
c[i][j] = std::inner_product(a[i].begin(), a[i].end(),
b.begin(), b.end(), 0,
std::plus<int>, multiplyRowElement);
}
}
return c;
}
Note that we also directly return the result of the operation rather than passing it as an inout parameter to the function, which is much cleaner.
It seems your otehr functions create access violations if any of the additional parameters is not equal to 0. In that case you iterate over the border of the array.
I am not really sure if this question is correctly tagged, as what you wrote seems a lot like plain C-Code. If you really need static storage, you can always just fall back to std::array
, which is more or less a wrapper around a plain C-style array.
So you should be able to replace int[256][256]
by std::array<std::array<int, 256>, 256>
. Note that in most times it is beneficial to have one array and use indexing to access the individual elements, but that is for another day.
Note that std::array
does not feature a constructor, so you would still have to manually fill it.
Since recently you can declare variables as constexpr
, which is a good replacement for your local variable m
.
Now regarding the actual code:
You should not use
using namespace std;
This is bad practice that will pollute the entire namespace needlessly. It is quite beneficial to get into the habit of writingstd::
whenever necessary.Your original loops in main all run the same length so justfill the elements once and dont interate so often
Regarding the respective functions you should be able to utilize quite a bit of functionality from the
algorithm
library.
First lets have a look at Naive_Multiply:
void Naive_Multiply(int a[256], int b[256], int c[256], int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = 0;
for (int t = 0; t < n; t++) {
c[i][j] = c[i][j] + a[i][t] * b[t][j];
}
}
}
}
Here you can use std::inner_product
constexpr int rowSize = 256;
using row = std::array<int, m>;
using mat = std::array<row , m>
mat Naive_Multiply(const mat& a, const mat& b)
{
mat c;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
auto multiplyRowElement = [j](const int a, const row& b) {
return a * b[j];
};
c[i][j] = std::inner_product(a[i].begin(), a[i].end(),
b.begin(), b.end(), 0,
std::plus<int>, multiplyRowElement);
}
}
return c;
}
Note that we also directly return the result of the operation rather than passing it as an inout parameter to the function, which is much cleaner.
It seems your otehr functions create access violations if any of the additional parameters is not equal to 0. In that case you iterate over the border of the array.
answered Dec 18 at 19:02
miscco
3,427517
3,427517
I am very grateful for your hints, but before using various functions, I must learn the principles of their work. So, that is why i'm not using it, i'm just learning the language. And what about the main problem? How to do the algorithm without recursive array creation?
– Emik
Dec 18 at 22:18
@Emik The C++-standard-library is part of the language (not part of the core language, but part of the C++ standard)
– chtz
yesterday
add a comment |
I am very grateful for your hints, but before using various functions, I must learn the principles of their work. So, that is why i'm not using it, i'm just learning the language. And what about the main problem? How to do the algorithm without recursive array creation?
– Emik
Dec 18 at 22:18
@Emik The C++-standard-library is part of the language (not part of the core language, but part of the C++ standard)
– chtz
yesterday
I am very grateful for your hints, but before using various functions, I must learn the principles of their work. So, that is why i'm not using it, i'm just learning the language. And what about the main problem? How to do the algorithm without recursive array creation?
– Emik
Dec 18 at 22:18
I am very grateful for your hints, but before using various functions, I must learn the principles of their work. So, that is why i'm not using it, i'm just learning the language. And what about the main problem? How to do the algorithm without recursive array creation?
– Emik
Dec 18 at 22:18
@Emik The C++-standard-library is part of the language (not part of the core language, but part of the C++ standard)
– chtz
yesterday
@Emik The C++-standard-library is part of the language (not part of the core language, but part of the C++ standard)
– chtz
yesterday
add a comment |
Emik is a new contributor. Be nice, and check out our Code of Conduct.
Emik is a new contributor. Be nice, and check out our Code of Conduct.
Emik is a new contributor. Be nice, and check out our Code of Conduct.
Emik is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209772%2fstrassen-vinograde-algorithm%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Brainstorming here, what do you mean no dynamic arrays? You're probably going to have to pre-declare storage for all the temporaries, using depth as well as row,col boundaries, so the recursive calls can share space in each NxN temporary. It might be ugly, but it will avoid declaring a bunch of extra MAX by MAX temporary arrays for tiny subproblems.
– Kenny Ostrom
Dec 16 at 18:24
Maybe we need source storage, but their number for example for 256x256 matrices will be very large.
– Emik
Dec 16 at 18:37
And I do not fully understand your idea.
– Emik
Dec 16 at 18:43
In addition, we can create dynamic arrays in main function, but it's not allowed to do it recursively.
– Emik
Dec 16 at 19:29
For reference, original question: stackoverflow.com/questions/53802871
– chtz
yesterday