
Список использованной литературы
Умножение матрицы на матрицу [электронный ресурс] // http://vm.psati.ru/online-math-sem-1/page-1-1-02-03.html
Алгоритм Штрассена [электронный ресурс] // http://ru.wikipedia.org/wiki/Алгоритм_Штрассена
Приложения
Приложение 1. Замеры времени, размерности 100 – 1200
Таблица 1. Зависимость времени (мс.) работы алгоритмов от размерностей матриц.
Размерность |
Классический |
Штрассена |
Штрассена (ускоренный) |
100 |
16 |
15 |
28 |
110 |
0 |
16 |
19 |
120 |
0 |
15 |
18 |
130 |
16 |
62 |
103 |
140 |
0 |
78 |
104 |
150 |
15 |
63 |
104 |
160 |
16 |
62 |
105 |
170 |
16 |
62 |
104 |
180 |
15 |
78 |
104 |
190 |
31 |
63 |
104 |
200 |
32 |
78 |
135 |
210 |
46 |
63 |
134 |
220 |
47 |
63 |
136 |
230 |
47 |
62 |
135 |
240 |
62 |
62 |
137 |
250 |
62 |
78 |
135 |
260 |
62 |
500 |
593 |
270 |
94 |
483 |
593 |
280 |
94 |
483 |
594 |
290 |
109 |
499 |
594 |
300 |
110 |
499 |
594 |
310 |
141 |
483 |
593 |
320 |
140 |
499 |
594 |
330 |
171 |
484 |
724 |
340 |
172 |
499 |
727 |
350 |
187 |
500 |
724 |
360 |
218 |
484 |
726 |
370 |
234 |
484 |
726 |
380 |
265 |
515 |
729 |
Размерность |
Классический |
Штрассена |
Штрассена (ускоренный) |
390 |
281 |
483 |
900 |
400 |
297 |
499 |
898 |
410 |
328 |
483 |
900 |
420 |
328 |
499 |
903 |
430 |
374 |
500 |
900 |
440 |
406 |
484 |
900 |
450 |
437 |
499 |
968 |
460 |
515 |
484 |
970 |
470 |
546 |
500 |
969 |
480 |
562 |
499 |
970 |
490 |
608 |
500 |
991 |
500 |
640 |
484 |
969 |
510 |
733 |
500 |
969 |
520 |
702 |
3447 |
3474 |
530 |
795 |
3479 |
3476 |
540 |
796 |
3588 |
3476 |
550 |
843 |
3463 |
3473 |
560 |
936 |
3478 |
3477 |
570 |
1014 |
3447 |
3477 |
580 |
1279 |
3463 |
4048 |
590 |
1061 |
3494 |
4050 |
600 |
1295 |
3463 |
4052 |
610 |
1264 |
3479 |
4055 |
620 |
1326 |
3494 |
4055 |
630 |
1404 |
3463 |
4056 |
640 |
1482 |
3494 |
4057 |
650 |
1560 |
3463 |
4812 |
660 |
1653 |
3510 |
4818 |
670 |
1669 |
3557 |
4819 |
680 |
2917 |
3557 |
4818 |
690 |
2200 |
3494 |
4802 |
700 |
2043 |
3510 |
4816 |
710 |
2216 |
3494 |
5107 |
720 |
2371 |
3557 |
5106 |
Размерность |
Классический |
Штрассена |
Штрассена (ускоренный) |
730 |
2450 |
3478 |
5115 |
740 |
2652 |
3494 |
5093 |
750 |
2668 |
3525 |
5109 |
760 |
2823 |
3495 |
5129 |
770 |
3042 |
3494 |
6030 |
780 |
3151 |
3526 |
6037 |
790 |
3244 |
3510 |
6050 |
800 |
3354 |
3479 |
6035 |
810 |
3791 |
3619 |
6034 |
820 |
3837 |
3619 |
6033 |
830 |
3915 |
3541 |
6020 |
840 |
4150 |
3572 |
6352 |
850 |
4509 |
3728 |
6345 |
860 |
4493 |
3713 |
6389 |
870 |
4883 |
3651 |
6366 |
880 |
5242 |
3681 |
6391 |
890 |
5366 |
3666 |
6391 |
900 |
5460 |
3588 |
6755 |
910 |
5382 |
3510 |
6786 |
920 |
6396 |
3588 |
6770 |
930 |
5944 |
3494 |
6771 |
940 |
6427 |
3541 |
6864 |
950 |
6630 |
3635 |
6755 |
960 |
7083 |
3650 |
6801 |
970 |
7566 |
3759 |
6927 |
980 |
7691 |
3728 |
6910 |
990 |
7246 |
3660 |
6973 |
1000 |
8296 |
3668 |
6911 |
1010 |
9904 |
3700 |
6942 |
1020 |
11770 |
3568 |
6926 |
1030 |
10717 |
25295 |
21606 |
1040 |
10537 |
25711 |
21622 |
1050 |
10004 |
25370 |
21591 |
1060 |
9767 |
25676 |
21700 |
Размерность |
Классический |
Штрассена |
Штрассена (ускоренный) |
1070 |
9218 |
25728 |
21575 |
1080 |
10634 |
25563 |
21622 |
1090 |
13240 |
25570 |
24149 |
1100 |
10651 |
25338 |
24289 |
1110 |
11423 |
25544 |
24258 |
1120 |
11050 |
25470 |
24227 |
1130 |
11312 |
25926 |
24259 |
1140 |
12468 |
25730 |
24134 |
1150 |
13514 |
25861 |
24602 |
1160 |
12926 |
25828 |
28064 |
1170 |
12748 |
25880 |
27846 |
1180 |
13746 |
25946 |
28127 |
1190 |
14537 |
26174 |
27862 |
1200 |
14902 |
26082 |
27752 |
Приложение 2. Замеры времени, размерности 500 – 4500
Таблица 2. Зависимость времени (мс.) работы алгоритмов от размерностей матриц.
Размерность |
Классический |
Штрассена |
Штрассена (ускоренный) |
500 |
546 |
485 |
967 |
1000 |
6956 |
3485 |
6878 |
1500 |
24704 |
24607 |
36009 |
2000 |
63220 |
24672 |
48852 |
2500 |
136142 |
191030 |
212285 |
3000 |
258350 |
196074 |
273624 |
3500 |
518202 |
193112 |
341890 |
4000 |
873557 |
195904 |
392076 |
4500 |
1359373 |
1482270 |
1324115 |
Приложение 3. Листинг
Класс Matrix
//---------------------------------------------------------------------------
#ifndef MatrixH
#define MatrixH
#pragma once
#include <ComCtrls.hpp>
#include <Windows.h>
#include <Math.h>
template <typename T>
class Matrix{
private:
int n;
T ** a;
int notZeroColumns; // количество ненулевых столбцов
int notZeroLines;
static Matrix<T> ** decomposeMatrix( Matrix<T> * const m );
Matrix<T> * buildMatrix( Matrix<T> ** const m );
static int isNormalSize( Matrix<T> * const m );
Matrix<T> * getNormalized(int nextPow);
Matrix<T> * __fastcall sp( Matrix<T> * const a, Matrix<T> * const b); // shtrassenProduct
bool inline isNull();
public:
Matrix< T >(int n, bool autoSet = true);
Matrix< T >* __fastcall classicProduct (Matrix< T > *m);
Matrix< T >* shtrassenProduct (Matrix< T > *m);
Matrix< T >* operator - (Matrix< T > * op);
Matrix< T >* operator + (Matrix< T > * op);
~Matrix< T >();
};
//---------------------------------------------------------------------------
template <typename T>
Matrix< T >::Matrix(int n, bool autoSet){
this->n = n;
a = new T*[ n ];
for (int i = 0; i < n; i ++){
a[ i ] = new T[ n ];
}
short p = RAND_MAX;
if ( autoSet ){
for (int i = 0; i < n; i ++)
for (int j = 0; j < n; j ++)
a[ i ][ j ] = (T)rand() ;
notZeroColumns = n;
notZeroLines = n;
} else {
notZeroColumns = 0;
notZeroLines = 0;
}
}
template <typename T>
Matrix< T >::~Matrix(){
for (int i = 0; i < n; i ++ )
delete[] a[i];
delete[] a;
}
template <typename T>
bool inline Matrix< T >::isNull(){
return ! (notZeroColumns && notZeroLines);
}
template <typename T>
Matrix< T >* __fastcall Matrix< T >::classicProduct(Matrix< T > *m){
Matrix *res = new Matrix(n, false);
T Aij = 0;
for (int i = 0; i < n; i ++){
for (int j = 0; j < n; j ++){
for (int t = 0; t < n; t ++)
Aij += (T)(a[ i ][ t ] * m->a[ t ][ j ]);
res->a[ i ][ j ] = Aij;
Aij = 0;
}
}
return res;
}
template <typename T>
Matrix< T >* Matrix< T >::shtrassenProduct(Matrix< T > *m){
// подготовка и запуск рекурсии
Matrix<T> * res = NULL,
* normalizedMatrixA = NULL,
* normalizedMatrixB = NULL;
if( int nextPow = isNormalSize( m )){
normalizedMatrixA = this->getNormalized( nextPow );
normalizedMatrixB = m->getNormalized( nextPow ); // подгон размера под степень двойки
} else {
normalizedMatrixA = this;
normalizedMatrixB = m;
}
res = sp( normalizedMatrixA, normalizedMatrixB);
// достаточно проверить "нормальность" одной из матриц
if( normalizedMatrixB != m ){
delete normalizedMatrixA; delete normalizedMatrixB; // удаляем порождённые матрицы
}
return res;
}
template <typename T>
Matrix<T> * __fastcall Matrix< T >::sp( Matrix<T> * const ma, Matrix<T> * const mb){
// только матрицы размера степени 2 !!!
Matrix<T> * res = NULL;
// выявление нулевой матрицы
if( ma->isNull() || mb->isNull() )
return new Matrix< T >( ma->n , false );
if(ma->n <= int (2 << 5)){
return ma->classicProduct(mb);
}
else {
Matrix<T> ** A = decomposeMatrix( ma ),
* A11 = A[0], * A12 = A[1],
* A21 = A[2], * A22 = A[3],
** B = decomposeMatrix( mb ),
* B11 = B[0], * B12 = B[1],
* B21 = B[2], * B22 = B[3],
* C11, * C12,* C21,* C22; // части результирующей матрицы
Matrix<T> * P1, * P2, * P3, * P4, // промежуточные вычисления
* P5, * P6, * P7, * sumBuf1, * sumBuf2;
sumBuf1 = *A11 + A22; sumBuf2 = *B11 + B22;
P1 = sp( sumBuf1, sumBuf2);
delete sumBuf1; delete sumBuf2;
sumBuf1 = *A21 + A22;
P2 = sp( sumBuf1, B11);
delete sumBuf1;
sumBuf1 = *B12 - B22;
P3 = sp( A11, sumBuf1);
delete sumBuf1;
sumBuf1 = *B21 - B11;
P4 = sp( A22, sumBuf1);
delete sumBuf1;
sumBuf1 = *A11 + A12;
P5 = sp( sumBuf1, B22);
delete sumBuf1;
sumBuf1 = *A21 - A11; sumBuf2 = *B11 + B12;
P6 = sp( sumBuf1, sumBuf2);
delete sumBuf1; delete sumBuf2;
delete A11; delete B11; delete B12;
sumBuf1 = *A12 - A22; sumBuf2 = *B21 + B22;
P7 = sp( sumBuf1, sumBuf2);
delete sumBuf1; delete sumBuf2;
delete A22; delete B22; delete A21; delete B21; delete A12;
delete[] A; delete[] B;
//------------------------------------------------------------------------------
sumBuf1 = *P1 + P4; sumBuf2 = *P5 + P7;
C11 = *sumBuf1 - sumBuf2;
delete sumBuf1; delete sumBuf2;
delete P7;
C12 = *P3 + P5;
delete P5;
C21 = *P2 + P4;
delete P4;
sumBuf1 = *P1 - P2; sumBuf2 = *P3 + P6;
C22 = *sumBuf1 + sumBuf2;
delete sumBuf1; delete sumBuf2;
delete P1; delete P2; delete P3; delete P6;
Matrix<T> * C[4] = {C11, C12, C21, C22};
res = buildMatrix( C );
delete C11; delete C12; delete C21; delete C22;
}
return res;
}
template <typename T>
Matrix<T> ** Matrix<T>::decomposeMatrix( Matrix<T> * const m ){
int size = m->n / 2, max = m->n,
dc = m->notZeroColumns - size,
firstPathCol = dc > 0 ? size : m->notZeroColumns,
scondPathCol = dc > 0 ? dc : 0, // количество ненулевых столбцов в матрицых 1 4 четверити
dl = m->notZeroLines - size,
firstPathLin = dl > 0 ? size : m->notZeroLines,
scondPathLin = dl > 0 ? dl : 0;
Matrix<T> ** res = new Matrix<T> * [4],
* A11 = new Matrix<T>( size, false ),
* A12 = new Matrix<T>( size, false ),
* A21 = new Matrix<T>( size, false ),
* A22 = new Matrix<T>( size, false );
res[0] = A11; res[1] = A12; res[2] = A21; res[3] = A22;
A11->notZeroColumns = firstPathCol; A11->notZeroLines = firstPathLin;
A12->notZeroColumns = scondPathCol; A12->notZeroLines = firstPathLin;
A21->notZeroColumns = firstPathCol; A21->notZeroLines = scondPathLin;
A22->notZeroColumns = scondPathCol; A22->notZeroLines = scondPathLin;
// выборка А11
for (int i = 0; i < size; i ++)
for ( int j = 0; j < size; j ++)
A11->a[i][j] = m->a[i][j];
// выборка А12
for (int i = 0; i < size && scondPathCol; i ++) // не копируем нули
for (int j = size; j < max; j ++)
A12->a[i][j - size] = m->a[i][j];
// выборка А21
for (int i = size; i < max && scondPathLin; i ++)
for (int j = 0; j < size; j ++)
A21->a[i - size][j] = m->a[i][j];
// выборка А22
for (int i = size; i < max && scondPathCol && scondPathLin; i ++)
for (int j = size; j < max; j ++)
A22->a[i - size][j - size] = m->a[i][j];
return res;
}
template <typename T>
Matrix<T> * Matrix<T>::buildMatrix( Matrix<T> ** const m ){
Matrix<T> * A11 = m[0], * A12 = m[1], * A21 = m[2], * A22 = m[3];
int halth = A11->n, size = A11->n * 2, i = 0, j = 0;
Matrix<T> * result = new Matrix<T>( size, false );
for ( i; i < halth; i ++)
for ( j; j < halth; j ++)
result->a[i][j] = A11->a[i][j];
for ( i = 0; i < halth; i ++)
for ( j = halth; j < size; j ++)
result->a[i][j] = A12->a[i][j - halth];
for ( i = halth; i < size; i ++)
for ( j = 0; j < halth; j ++)
result->a[i][j] = A21->a[i - halth][j];
for ( i = halth; i < size; i ++)
for ( j = halth; j < size; j ++)
result->a[i][j] = A22->a[i - halth][j - halth];
result->notZeroColumns = size;
result->notZeroLines = size;
return result;
}
template <typename T>
Matrix<T> * Matrix< T >::getNormalized( int nextPow ){
// считаем что исходная матрица меньше
Matrix<T> * res = new Matrix<T>(nextPow, false);
for (int i = 0; i < n; i ++)
for (int j = 0; j < n; j ++)
res->a[i][j] = a[i][j];
res->notZeroColumns = n; res->notZeroLines = n;
return res;
}
template <typename T>
int Matrix< T >::isNormalSize( Matrix<T> * const m ){
// возвращать 0 когда степень 2ки
int power = 2;
while( power < m->n )
power <<= 1;
return m->n & power ? 0 : power;
}
template <typename T>
Matrix< T >* Matrix<T>::operator - (Matrix< T > * op){
Matrix<T> *res = new Matrix<T>(n, false);
for (int i = 0; i < n; i ++)
for (int j = 0; j < n; j ++)
res->a[i][j] = T(a[i][j] - op->a[i][j]);
res->notZeroColumns = notZeroColumns > op->notZeroColumns ?
notZeroColumns : op->notZeroColumns;
res->notZeroLines = notZeroLines > op->notZeroLines ?
notZeroLines : op->notZeroLines;
return res;
}
template <typename T>
Matrix< T >* Matrix<T>::operator + (Matrix< T > * op){
Matrix<T> *res = new Matrix<T>(n, false);
for (int i = 0; i < n; i ++)
for (int j = 0; j < n; j ++)
res->a[i][j] = T (a[i][j] + op->a[i][j]);
res->notZeroColumns = notZeroColumns > op->notZeroColumns ?
notZeroColumns : op->notZeroColumns;
res->notZeroLines = notZeroLines > op->notZeroLines ?
notZeroLines : op->notZeroLines;
return res;
}
#endif
Оболочка для тестирования
//---------------------------------------------------------------------------
#ifndef MainFormH
#define MainFormH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
#include <ExtCtrls.hpp>
#include <Grids.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Start;
TStringGrid *Results;
TGroupBox *GroupBox1;
TGroupBox *GroupBox2;
TRichEdit *Output;
TGroupBox *GroupBox3;
TLabel *Label3;
TEdit *StartSize;
TLabel *Label4;
TEdit *EndSize;
TLabel *Label5;
TEdit *StepBySize;
TLabel *Label6;
TEdit *NumberExperements;
TCheckBox *LogCheckBox;
void __fastcall StartClick(TObject *Sender);
private:
void __fastcall doExperementCicle( short experementCircleNumber, short experementCount, short matrixSize,
TTime & classicTime, TTime & strassenTime);
public: // User declarations
__fastcall TForm1(TComponent* Owner);
void prepareOutput();
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "MainForm.h"
#include "Matrix.h"
#include <iostream>
using namespace std;
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#define TYPE short
#define LOG_FILE_NAME_PREFIX "logs/LOG "
#define LOG_FILE_EXTENSION ".txt"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Results->Cells[0][0] = "Алгоритм";
}
//---------------------------------------------------------------------------
void prepareTable(TStringGrid * table, int experementCount){
AnsiString * str;
for ( int i = 0; i < experementCount; i ++){
table->ColCount += 1;
str = new AnsiString();
str->printf("Тест №%i",i + 1);
table->Cells[i + 1][0] = *str;
delete str;
}
}
void __fastcall TForm1::doExperementCicle( short experementCircleNumber, short experementCount, short matrixSize,
TTime & classicTime, TTime & strassenTime){
Matrix<TYPE> m( matrixSize, true ), m1( matrixSize, true ), *m2; // рабочие матрицы
AnsiString *str; // для вывода
unsigned short hour, min, sec, msec; // время для вывода
TTime t1, t2, dt, // время работы
*classicTimes = new TTime[experementCount], // для вычисления среднего времени работы алгоритмов
*shtrassenTimes = new TTime[experementCount];
Results->RowCount += 2;
int classicLineNumber = 2 * experementCircleNumber + 1;
for ( int i = 0; i < experementCount; i ++){
str = new AnsiString("Клас.");
str->cat_printf("(n=%i)", matrixSize);
Results->Cells[0][classicLineNumber] = str->c_str();
delete str;
str = new AnsiString("Штрас.");
str->cat_printf("(n=%i)", matrixSize);
Results->Cells[0][classicLineNumber + 1] = str->c_str();
delete str;
// запуск теста классического алгоритма
str = new AnsiString();
str->printf("Серия %i. Тест %i Классического алгоритма с n=%i начат...",
experementCircleNumber + 1, i + 1, matrixSize);
Output->Lines->Add(*str);
SendMessage(Output->Handle, EM_LINESCROLL, 0, MAKEWORD(SB_LINEDOWN, 0));
//Update();
delete str;
t1 = Time();
m2 = m.classicProduct( &m1 );
t2 = Time();
dt = t2 - t1;
classicTimes[ i ] = dt;
DecodeTime(dt, hour, min, sec, msec);
str = new AnsiString();
str->printf("%im: %is: %ims", min, sec, msec );
Results->Cells[i + 1][classicLineNumber] = *str;
delete str;
delete m2;
// запуск теста алгоритма Штрассена
str = new AnsiString();
str->printf("Серия %i. Тест %i алгоритма Штрассена с n=%i начат...",
experementCircleNumber + 1, i + 1, matrixSize);
Output->Lines->Add(*str);
delete str;
SendMessage(Output->Handle, EM_LINESCROLL, 0, MAKEWORD(SB_LINEDOWN, 0));
//Update();
t1 = Time();
m2 = m.shtrassenProduct( &m1 );
t2 = Time();
dt = t2 - t1;
shtrassenTimes[ i ] = dt;
DecodeTime(dt, hour, min, sec, msec);
str = new AnsiString();
str->printf("%im: %is: %ims", min, sec, msec );
Results->Cells[i + 1][classicLineNumber + 1] = *str;
delete str;
delete m2;
Repaint();
}
// подсчёт среднего времени
t1 = 0; t2 = 0;
for (int i = 0; i < experementCount; i ++){
t1 += classicTimes[ i ];
t2 += shtrassenTimes[ i ];
}
delete[] classicTimes; delete[] shtrassenTimes;
t1 = t1.operator double() / experementCount;
t2 = t2.operator double() / experementCount;
classicTime = t1; strassenTime = t2;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::StartClick(TObject *Sender)
{
int currentMatrixSize = 0,
maxMatrixSize = 0,
stepBy = 0,
numberExperements = 0;
try {
currentMatrixSize = StartSize->Text.ToInt();
maxMatrixSize = EndSize->Text.ToInt();
stepBy = StepBySize->Text.ToInt();
numberExperements = NumberExperements->Text.ToInt();
}
catch (...) {
ShowMessage("Необходимо вводить только целочисленные значения.");
}
if ( currentMatrixSize > 0 && numberExperements > 0){
prepareOutput();
prepareTable( Results, numberExperements );
AnsiString *str;
// ведение лога
TDateTime dt = TTime::CurrentDateTime();
str = new AnsiString( LOG_FILE_NAME_PREFIX );
str->cat_printf( "%s", dt.FormatString("dd-mm-yyyy (hhч nnм ssс)") );
str->cat_printf( LOG_FILE_EXTENSION );
FILE *file;
file = this->LogCheckBox->Checked ?
fopen(str->c_str(), "w") : NULL;
delete str;
if( file ){
AnsiString text( "Испытания от: " ),
line( "---------------------------------------------------------------------------------------------------");
text.cat_printf("%s\n", dt.DateTimeString());
text.cat_printf("%s\n", line);
text.cat_printf("%s\n\n", "Входные параметры испытаний:");
text.cat_printf("%s %i\n", "Начальный размер матриц:" , currentMatrixSize);
text.cat_printf("%s %i\n", "Максимальный размер матриц:" , maxMatrixSize);
text.cat_printf("%s %i\n", "Шаг увеличения размера матриц:" , stepBy);
text.cat_printf("%s %i\n", "Количество повторений одного опыта:" , numberExperements);
text.cat_printf("%s\n\n", line);
text.cat_printf("%s\n", "n - размерность матриц");
text.cat_printf("%s\n", "ВК - время работы классического алгоритма (в миллисекундах)");
text.cat_printf("%s\n\n", "ВШ - время работы алгоритма Штрассена (в миллисекундах)");
text.cat_printf("%s\n", "n\tВК\tВШ");
fwrite(text.c_str(), text.Length(), 1, file);
}
unsigned short hour, min, sec, msec;
TTime t1, t2;
short experementCicleNumber = 0;
do{
this->doExperementCicle(experementCicleNumber ++ , numberExperements, currentMatrixSize, t1, t2);
// для лога
unsigned int classicTime, shtrassenTime;
Output->Lines->Add("Подведение итогов:");
str = new AnsiString();
DecodeTime(t1, hour, min, sec, msec);
classicTime = min * 60000 + sec * 1000 + msec;
str->printf(
"среднее время работы классического алгоритма при n=%i : %im, %is, %ims", currentMatrixSize, min, sec, msec);
Output->Lines->Add(*str);
str->Delete(0, str->Length());
DecodeTime(t2, hour, min, sec, msec);
shtrassenTime = min * 60000 + sec * 1000 + msec;
str->printf (
"среднее время работы алгоритма Штрассена при n=%i : %im, %is, %ims", currentMatrixSize, min, sec, msec);
Output->Lines->Add(*str);
delete str;
// ведение лога
if( file ){
str = new AnsiString();
str->printf ("%i\t%i\t%i\n", currentMatrixSize, classicTime, shtrassenTime);
fwrite(str->c_str(), str->Length(), 1, file);
delete str;
}
currentMatrixSize += stepBy;
} while( currentMatrixSize <= maxMatrixSize );
// ведение лога
if( file ) fclose( file );
ShowMessage("Работа окончена");
}
}
void TForm1::prepareOutput(){
int count = Results->ColCount;
if( count > 1 )
for ( ; count > 1; count -- )
Results->Cols[count - 1]->Clear();
Results->ColCount = 1;
Results->RowCount = 1;
Output->Lines->Clear();
}
//---------------------------------------------------------------------------
1 Погружение в рекурсию происходит до тех пор, пока размерность сомножителей не станет равной двум.