bool Multiply2(Matrix& m1, Matrix& m2, Matrix& res)
{
bool bRet = false;
do
{
if( m1.row != m2.col ) break;
if( m1.col != res.col ) break;
if( m2.row != res.row ) break;
initZero(res);
for(int i=0; i<m1.col; i++){
for(int j=0; j<m1.row; j++){
for(int k=0; k<m2.row;){
int n = m2.row - k;
switch( n % 4 ) {
case 0: res.matrix[i][k] += m1.matrix[i][j] * m2.matrix[j][k]; k++;
case 3: res.matrix[i][k] += m1.matrix[i][j] * m2.matrix[j][k]; k++;
case 2: res.matrix[i][k] += m1.matrix[i][j] * m2.matrix[j][k]; k++;
case 1: res.matrix[i][k] += m1.matrix[i][j] * m2.matrix[j][k]; k++;
}
}
}
}
bRet = true;
} while(0);
return bRet;
}
#include <stdio.h>
#include <stdlib.h>
typedef struct _Matrix
{
int row, col;
float **matrix;
} Matrix;
typedef struct _Point
{
int x, y;
} Point;
typedef struct _Rect
{
Point st, ed;
} Rect;
bool mult(Matrix& m1, Rect& r1, Matrix& m2, Rect& r2, Matrix& res, Rect& r3)
{
bool bRet = false;
do
{
int col1 = r1.ed.y - r1.st.y;
int row1 = r1.ed.x - r1.st.x;
int col2 = r2.ed.y - r2.st.y;
int row2 = r2.ed.x - r2.st.x;
int col3 = r3.ed.y - r3.st.y;
int row3 = r3.ed.x - r3.st.x;
if( row1 != col2 ) break;
if( col1 != col3 ) break;
if( row2 != row3 ) break;
if( col1 < 0 || row1 < 0 || col2 < 0 || row2 < 0 ) break;
if( col1 != col3 || row2 != row3 ) break;
for(int i=0; i<col1; i++){
for(int j=0; j<row2; j++){
float e = 0.0f;
for(int k=0; k<row1; k++){
e += m1.matrix[r1.st.y+i][r1.st.x+k] * m2.matrix[r2.st.y+k][r2.st.x+j];
}
res.matrix[r3.st.y+i][r3.st.x+j];
}
}
bRet = true;
} while(0);
return bRet;
}
bool add(Matrix& m1, Rect& r1, Matrix& m2, Rect& r2, Matrix& res, Rect& r3)
{
bool bRet = false;
do
{
int col1 = r1.ed.y - r1.st.y;
int row1 = r1.ed.x - r1.st.x;
int col2 = r2.ed.y - r2.st.y;
int row2 = r2.ed.x - r2.st.x;
int col3 = r3.ed.y - r3.st.y;
int row3 = r3.ed.x - r3.st.x;
if( row1 != row2 || row1 != row3 ) break;
if( col1 != col2 || col1 != col3 ) break;
if( col1 < 0 || row1 < 0 || col2 < 0 || row2 < 0 ) break;
if( col1 != col3 || row2 != row3 ) break;
for(int i=0; i<col1; i++){
for(int j=0; j<row1; j++){
res.matrix[r3.st.y+i][r3.st.x+j] = m1.matrix[r1.st.y+i][r1.st.x+j] + m2.matrix[r2.st.y+i][r2.st.x+j];
}
}
bRet = true;
} while(0);
return bRet;
}
bool sub(Matrix& m1, Rect& r1, Matrix& m2, Rect& r2, Matrix& res, Rect& r3)
{
bool bRet = false;
do
{
int col1 = r1.ed.y - r1.st.y;
int row1 = r1.ed.x - r1.st.x;
int col2 = r2.ed.y - r2.st.y;
int row2 = r2.ed.x - r2.st.x;
int col3 = r3.ed.y - r3.st.y;
int row3 = r3.ed.x - r3.st.x;
if( row1 != row2 || row1 != row3 ) break;
if( col1 != col2 || col1 != col3 ) break;
if( col1 < 0 || row1 < 0 || col2 < 0 || row2 < 0 ) break;
if( col1 != col3 || row2 != row3 ) break;
for(int i=0; i<col1; i++){
for(int j=0; j<row1; j++){
res.matrix[r3.st.y+i][r3.st.x+j] = m1.matrix[r1.st.y+i][r1.st.x+j] - m2.matrix[r2.st.y+i][r2.st.x+j];
}
}
bRet = true;
} while(0);
return bRet;
}
float **make2dArray(int rows, int cols)
{
float **x = NULL;
int height = cols, width = rows;
x = (float **)calloc(height, sizeof(float*));
x[0] = (float *)calloc(width*height, sizeof(float));
for(int i=1; i<height; i++)
x[i] = x[i-1]+width;
return x;
}
void delete2dArray(float **arr)
{
if( arr != NULL ){
if( arr[0] != NULL )
free(arr[0]);
free(arr);
}
arr = NULL;
}
void initRandom(Matrix& m)
{
for(int i=0; i<m.col; i++){
for(int j=0; j<m.row; j++){
m.matrix[i][j] = (float)(rand()%4);
}
}
}
void initZero(Matrix& m)
{
for(int i=0; i<m.col; i++){
for(int j=0; j<m.row; j++){
m.matrix[i][j] = (float)(0.0f);
}
}
}
bool Multiply(Matrix& m1, Matrix& m2, Matrix& res)
{
bool bRet = false;
do
{
if( m1.row != m2.col ) break;
if( m1.col != res.col ) break;
if( m2.row != res.row ) break;
for(int i=0; i<m1.col; i++){
for(int j=0; j<m2.row; j++){
float e = 0.0f;
for(int k=0; k<m1.row; k++){
e += m1.matrix[i][k] * m2.matrix[k][j];
}
res.matrix[i][j] = e;
}
}
bRet = true;
} while(0);
return bRet;
}
bool Multiply2(Matrix& m1, Matrix& m2, Matrix& res)
{
bool bRet = false;
do
{
if( m1.row != m2.col ) break;
if( m1.col != res.col ) break;
if( m2.row != res.row ) break;
initZero(res);
for(int i=0; i<m1.col; i++)
{
for(int j=0; j<m1.row; j++)
{
int k = 0;
int n = (m2.row-1)/4;
switch( m2.row % 4 ) {
case 0: do{ res.matrix[i][k] += m1.matrix[i][j] * m2.matrix[j][k]; k++;
case 3: res.matrix[i][k] += m1.matrix[i][j] * m2.matrix[j][k]; k++;
case 2: res.matrix[i][k] += m1.matrix[i][j] * m2.matrix[j][k]; k++;
case 1: res.matrix[i][k] += m1.matrix[i][j] * m2.matrix[j][k]; k++;
}while( n-- > 0);
}
}
//for(int j=0; j<m1.row; j++)
//{
// int k = 0;
// switch( m2.row % 4 ) {
// case 0: res.matrix[i][k] += m1.matrix[i][j] * m2.matrix[j][k]; k++;
// case 3: res.matrix[i][k] += m1.matrix[i][j] * m2.matrix[j][k]; k++;
// case 2: res.matrix[i][k] += m1.matrix[i][j] * m2.matrix[j][k]; k++;
// case 1: res.matrix[i][k] += m1.matrix[i][j] * m2.matrix[j][k]; k++;
// }
// int n = (m2.row - k)/4;
// while( n --> 0 )
// {
// res.matrix[i][k] += m1.matrix[i][j] * m2.matrix[j][k];
// res.matrix[i][k+1] += m1.matrix[i][j] * m2.matrix[j][k+1];
// res.matrix[i][k+2] += m1.matrix[i][j] * m2.matrix[j][k+2];
// res.matrix[i][k+3] += m1.matrix[i][j] * m2.matrix[j][k+3];
// k += 4;
// }
//}
}
bRet = true;
} while(0);
return bRet;
}
bool printMatrix(Matrix& m)
{
bool bRet = false;
do
{
for(int i=0; i<m.col; i++){
for(int j=0; j<m.row; j++){
printf("%7.1f ",m.matrix[i][j]);
}printf("\n");
}printf("\n");
bRet = true;
} while(0);
return bRet;
}
bool makeMatrix(Matrix& m, int col, int row)
{
m.matrix = make2dArray(row, col);
m.col = col;
m.row = row;
return true;
}
bool deleteMatrix(Matrix& m)
{
delete2dArray(m.matrix);
m.col = 0;
m.row = 0;
return true;
}
bool compareMatrix(Matrix& m1, Matrix& m2)
{
bool bRet = false;
do
{
if( m1.row != m2.row ) break;
if( m1.col != m2.col ) break;
for(int i=0; i<m1.col; i++){
for(int j=0; j<m1.row; j++){
if( m1.matrix[i][j] != m2.matrix[i][j] )
return false;
}
}
bRet = true;
} while(0);
return bRet;
}
int main(int argc, char *argv[])
{
Matrix m1, m2, res1, res2;
for(int x=0; x<10; x++)
for(int i=4; i<10; i++)
for(int j=3; j<10; j++)
for(int k=5; k<10; k++){
bool bRet = false;
do
{
makeMatrix(m1, i, j);
makeMatrix(m2, j, k);
makeMatrix(res1, m1.col, m2.row);
makeMatrix(res2, m1.col, m2.row);
initRandom(m1);
initRandom(m2);
Multiply(m1, m2, res1);
Multiply2(m1, m2, res2);
//printMatrix(res1);
//printMatrix(res2);
if( compareMatrix(res1, res2) ){
printf("result = true\n");
}
else{
printf("result = false\n");
break;
}
deleteMatrix(m1);
deleteMatrix(m2);
bRet = true;
} while(0);
if( bRet == false ){ printf("assert!!\n"); system("pause"); return 0; }
}
system("pause");
return 0;
}
'c/c++' 카테고리의 다른 글
크기 0짜리 배열 (0) | 2012.10.04 |
---|---|
SSE2를 이용한 행렬 곱하기 (1) | 2012.09.13 |
c++ vector 등 연속 메모리 컨테이너를 배열처럼 쓰는 방법 (0) | 2012.09.09 |
multimap에서 equal_range()로 아무것도 못찾은 경우 (0) | 2012.09.01 |
STL iterator로 erase()사용시 주의해야할 점 (0) | 2012.08.27 |