본문 바로가기

Programming/C/C++

3x3 행렬 코딩

앞선 포스팅의 내용을 코딩 한 것입니다. 서적이 옛날에 나왔다 보니까 엄청난 포인터의 작렬이군요 ;ㅅ; 일단 코드의 내용입니다. 딱히 어려운 부분이 없어서 그냥 원문 타이핑 했구요, main부분은 나와있지 않아서 직접 작성 했습니다. 또한 printMatrix(..) 함수는 값 제대로 들어갔는지 확인 차 작성 했구요.
   
#include <stdlib.h>
#include <stdio.h>

typedef struct
{
	float mat[3][3];	// the rows and columns
} matrix3x3_t;

void MatrixAdd(matrix3x3_t* matrixA, matrix3x3_t* matrixB, matrix3x3_t* resultMatrix)
{
	// add two matrices, A and B, together and store result in resultMatrix

	// loop through all the elements of each matrix
	for(int row = 0 ; row < 3 ; ++row)
	{
		for(int col = 0 ; col < 3 ; ++col)
		{
			// add the current element of each matrix
			resultMatrix->mat[row][col] = matrixA->mat[row][col]+
										  matrixB->mat[row][col];
		} // end for col
	} // end for row
} // end MatrixAdd

void ScalarMatrixMult(float scalarValue,
					  matrix3x3_t* matrixA,
					  matrix3x3_t* resultMatrix)
{
	// perform scalar-matrix multiplication, return result Matrix
	
	// loop through entire matrix
	for(int row = 0 ; row < 3 ; ++row)
	{
		for(int col = 0 ; col < 3 ; ++col)
		{
			// multiply scalar and current element
			resultMatrix->mat[row][col] = scalarValue*matrixA->mat[row][col];
		} //  end for col
	} // end for row
} //  end ScalarMatrixMult

void MatrixMult(matrix3x3_t* matrixA, matrix3x3_t* matrixB, matrix3x3_t* resultMatrix)
{
	// multiply two matrices together and return resultMatrix

	float sum;	// used to store sum of multiplications
	
	for(int row = 0 ; row < 3 ; ++row)
	{
		for(int col = 0 ; col < 3 ; ++col)
		{
			sum = 0;	// reset to zero

			// multiply the row of A by the column of B
			for(int k = 0 ; k < 3 ; ++k)
			{
				sum += matrixA->mat[row][k]*matrixB->mat[k][col];
			} // end for k

			resultMatrix->mat[row][col] = sum;	// store sum of multiples
		} // end for col
	} // end for row
} // end MatrixMult

void printMatrix(matrix3x3_t* matrixA)
{
	for(int row = 0 ; row < 3 ; ++row)
	{
		for(int col = 0 ; col < 3 ; ++col)
			printf("%lf\t", matrixA->mat[row][col]);
		printf("\n");
	}
	printf("\n");
}


int main()
{
	matrix3x3_t* sampleA = (matrix3x3_t*)malloc(sizeof(matrix3x3_t));
	matrix3x3_t* sampleB = (matrix3x3_t*)malloc(sizeof(matrix3x3_t));
	matrix3x3_t* sampleR = (matrix3x3_t*)malloc(sizeof(matrix3x3_t));

	sampleA->mat[0][0] = 1.0;
	sampleA->mat[0][1] = 2.0;
	sampleA->mat[0][2] = 3.0;
	sampleA->mat[1][0] = 0.0;
	sampleA->mat[1][1] = 4.0;
	sampleA->mat[1][2] = 3.0;
	sampleA->mat[2][0] = 1.0;
	sampleA->mat[2][1] = 7.0;
	sampleA->mat[2][2] = 2.0;
	
	sampleB->mat[0][0] = 0.0;
	sampleB->mat[0][1] = 3.0;
	sampleB->mat[0][2] = 4.0;
	sampleB->mat[1][0] = 2.0;
	sampleB->mat[1][1] = 1.0;
	sampleB->mat[1][2] = 5.0;
	sampleB->mat[2][0] = 4.0;
	sampleB->mat[2][1] = 2.0;
	sampleB->mat[2][2] = 3.0;

	MatrixAdd(sampleA, sampleB, sampleR);
	printMatrix(sampleR);

	ScalarMatrixMult(2.0, sampleA, sampleR);
	printMatrix(sampleR);

	MatrixMult(sampleA, sampleB, sampleR);
	printMatrix(sampleR);

	free(sampleA);
	free(sampleB);
	free(sampleR);

	system("pause");
	return 0;
}

   
아래는 c++스타일로 한번 만들어 봤습니다. 그냥 간단하게 돌아가는 거니까 복잡하게 만들지는 않았어요 :-D
   
Matrix33.h
#pragma once
#include <array>

class Matrix33
{
private:
	std::tr1::array<std::tr1::array<float, 3>, 3> elem;

public:
	Matrix33(void);
	~Matrix33(void);

	void Show();	// print it self

	const float &operator()(const size_t &row, const size_t &col) const;	// r-value;
	float &operator()(const size_t &row, const size_t &col);				// l-value;
	
	friend Matrix33 operator+(const Matrix33 &matirxA, const Matrix33 &matrixB);
	friend Matrix33 operator*(const Matrix33 &matirxA, const Matrix33 &matrixB);
	friend Matrix33 operator*(const float &scalar, const Matrix33 &matrix);

};

   
Matrix33.cpp
#include "Matrix33.h"
#include <cstdio>

Matrix33::Matrix33(void)
{
	for(size_t row = 0 ; row < 3 ; ++row)
		for(size_t col = 0 ; col < 3 ; ++col)
			elem[row][col] = 0.0;
}


Matrix33::~Matrix33(void)
{
}

void Matrix33::Show()
{
	for(size_t row = 0 ; row < 3 ; ++row)
	{
		for(size_t col = 0 ; col < 3 ; ++col)
			printf("%lf\t", elem[row][col]);
		printf("\n");
	}
	printf("\n");
}

const float &Matrix33::operator()(const size_t &row, const size_t &col) const
{
	if(row > 2 || col > 2)
		return 0;

	return elem[row][col];
}

float &Matrix33::operator()(const size_t &row, const size_t &col)
{
	if(row > 2 || col > 2)
		return elem[0][0];		// 사실 l-value라 실수 안하길 바랄뿐.....

	return elem[row][col];
}

Matrix33 operator+(const Matrix33 &matrixA, const Matrix33 &matrixB)
{
	Matrix33 result;

	for(size_t row = 0 ; row < 3 ; ++row)
		for(size_t col = 0 ; col < 3 ; ++col)
			result.elem[row][col] = matrixA.elem[row][col] + matrixB.elem[row][col];

	return result;
}

Matrix33 operator*(const Matrix33 &matrixA, const Matrix33 &matrixB)
{
	Matrix33 result;	// 생성시 0으로 초기화 되므로 일일이 초기화 할 필요는 없다.
	
	for(size_t row = 0 ; row < 3 ; ++row)
		for(size_t col = 0 ; col < 3 ; ++col)
			for(int k = 0 ; k < 3 ; ++k)
				result.elem[row][col] += matrixA.elem[row][k] * matrixB.elem[k][col];

	return result;
}

Matrix33 operator*(const float &scalar, const Matrix33 &matrix)
{
	Matrix33 result;

	for(size_t row = 0 ; row < 3 ; ++row)
		for(size_t col = 0 ; col < 3 ; ++col)
			result.elem[row][col] = scalar*matrix.elem[row][col];

	return result;

}

 
   
main.cpp
#include "Matrix33.h"

int main()
{
	// 내꺼....ㅋ
	Matrix33 mA, mB, mR;

	mA(0, 0) = 1.0;
	mA(0, 1) = 2.0;
	mA(0, 2) = 3.0;
	mA(1, 0) = 0.0;
	mA(1, 1) = 4.0;
	mA(1, 2) = 3.0;
	mA(2, 0) = 1.0;
	mA(2, 1) = 7.0;
	mA(2, 2) = 2.0;

	mB(0, 0) = 0.0;
	mB(0, 1) = 3.0;
	mB(0, 2) = 4.0;
	mB(1, 0) = 2.0;
	mB(1, 1) = 1.0;
	mB(1, 2) = 5.0;
	mB(2, 0) = 4.0;
	mB(2, 1) = 2.0;
	mB(2, 2) = 3.0;


	mR = mA + mB;
	mR.Show();

	mR = 2.0 * mA;
	mR.Show();

	mR = mA * mB;
	mR.Show();

	system("pause");
	return 0;
}

   
네, 뭐 물론 결과는 같지만, C냐 C++이냐는 선택의 문제니까요. java여도 다를바는 없을 거 같습니다. 결국엔 내부구현과 외부에서의 사용을 얼마나 용이하게 했느냐 같아요.
   
실행 결과


'Programming > C/C++' 카테고리의 다른 글

virtual keyword in C++  (0) 2012.08.01
임의의 벡터간 각도 구하기  (0) 2011.12.15
C reference 정리 pdf  (0) 2011.09.03
포인터 2차 동적 할당  (0) 2011.02.21
Random double 값 추출하기  (0) 2011.02.10