다음은 행렬 곱셈을 수행하는 C++ 언어 소스이다.
행의 수, 열의 수. 그리고 두 행렬의 요소들을 모두 컨솔에서 입력해야 한다.
소스는 http://www.physics.utah.edu/~detar/lessons/c++/matrices/node4.html 의 것을 다소 수정한 것이다.
// Filename: testSomeMat-03.cpp
//
// Copmpile: cl /EHsc testSomeMat-03.cpp
// Execute: testSomeMat-03
//
// Date: 2003.9. 20.
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
typedef vector<double> Vec;
typedef vector<Vec> Mat;
Vec operator*(const Mat &a, const Vec &x){
int i,j;
int m = a.size();
int n = x.size();
Vec prod(m);
for(i = 0; i < m; i++){
prod[i] = 0.;
for(j = 0; j < n; j++)
prod[i] += a[i][j]*x[j];
}
return prod;
}
Mat operator*(const Mat &a, const Mat &b) {
int i, j, k;
int m = a.size();
int n = a[0].size();
int p = b[0].size();
Mat c;
for(i = 0; i < m; i++){
Vec row(p);
for(j = 0; j < p; j++) {
row[j] = 0.;
for(k = 0; k < n; k++) {
row[j] += a[i][k]*b[k][j];
}
}
c.push_back(row);
}
return c;
}
void printMatrix(const Mat &a, int width) {
int i, j;
int m = a.size();
int n = a[0].size();
for(i = 0; i < m; i++) {
if (i == 0)
cout << " [[";
else
cout << " [";
for(j = 0; j < n; j++) {
cout << " " << setw(width) << a[i][j];
}
if (i < m - 1)
cout << " ]";
else
cout << " ]]";
cout << "\n";
}
}
int main() {
int i, j, k, m, n, p;
cout << "첫째 행렬의 행의 수: ";
cin >> m;
cout << "첫째 행렬의 열의 수: ";
cin >> n;
cout << "둘째 행렬의 열의 수: ";
cin >> p;
cout << "\n";
// 첫째 행렬과 이 행렬의 입력을 위한 벡터 선언
Mat a;
Vec row(n);
cout << "첫째 행렬의 요소들을 입력하시오.\n";
for(i = 0; i < m; i++){
for(j = 0; j < n; j++)cin >> row[j];
a.push_back(row);
}
// 둘째 행렬과 이 행렬의 입력을 위한 벡터 선언
Mat b;
Vec row2(p);
cout << "둘째 행렬의 요소들을 입력하시오.\n";
for(i = 0; i < n; i++){
for(j = 0; j < p; j++)cin >> row2[j];
b.push_back(row2);
}
Mat c = a*b;
cout << "\nA = \n";
printMatrix(a, 8);
cout << "\nB = \n";
printMatrix(b, 8);
cout << "\nA*B = \n";
printMatrix(c, 8);
return 0;
}
/*
Output:
첫째 행렬의 행의 수: 3
첫째 행렬의 열의 수: 3
둘째 행렬의 열의 수: 1
첫째 행렬의 요소들을 입력하시오.
2 5 6
1 2 0
9 7 1
둘째 행렬의 요소들을 입력하시오.
4 1 2
A =
[[ 2 5 6 ]
[ 1 2 0 ]
[ 9 7 1 ]]
B =
[[ 4 ]
[ 1 ]
[ 2 ]]
A*B =
[[ 25 ]
[ 6 ]
[ 45 ]]
*/
다음은 정사각행렬의 행렬식을 구하는 소스이다.
// Filename: determinant-04.cpp
//
// Compile: g++ -std=c++11 -o determinant-04 determinant-04.cpp
// Execute: ./determinant-04
//
// or
//
// Compile: cl /EHsc determinant-04.cpp
// Execute: determinant-04
//
// Date: 2013. 9. 20.
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cstring>
using namespace std;
typedef vector<double> Vec;
typedef vector<Vec> Mat;
Vec operator*(const Mat &a, const Vec &x){
int i,j;
int m = a.size();
int n = x.size();
Vec prod(m);
for(i = 0; i < m; i++){
prod[i] = 0.;
for(j = 0; j < n; j++)
prod[i] += a[i][j]*x[j];
}
return prod;
}
Mat operator*(const Mat &a, const Mat &b) {
int i, j, k;
int m = a.size();
int n = a[0].size();
int p = b[0].size();
Mat c;
for(i = 0; i < m; i++){
Vec row(p);
for(j = 0; j < p; j++) {
row[j] = 0.;
for(k = 0; k < n; k++) {
row[j] += a[i][k]*b[k][j];
}
}
c.push_back(row);
}
return c;
}
void printMatrix(const Mat &a, int width) {
int i, j;
int m = a.size();
int n = a[0].size();
for(i = 0; i < m; i++) {
if (i == 0)
cout << " [[";
else
cout << " [";
for(j = 0; j < n; j++) {
cout << " " << setw(width) << a[i][j];
}
if (i < m - 1)
cout << " ]";
else
cout << " ]]";
cout << "\n";
}
}
void printPermutation(const vector<int> pmt, int counter)
{
int n = pmt.size();
cout << "[";
if (n > 0)
{
cout << " " << pmt[0];
if (n > 1)
{
for (int i = 1; i < n; i++)
{
cout << ", " << pmt[i];
}
}
cout << " ";
}
cout << "]";
if ((counter % 2) == 0)
cout << " -- even --";
else
cout << " -- odd --";
cout << endl;
}
void swap(vector<int> &pmt, int i, int j)
{
int x = pmt[j];
pmt[j] = pmt[i];
pmt[i] = x;
}
void doPermute(const Mat &mat, int dim, vector<int> pmt, int size, int &cnt, double &det, bool show_flag)
{
double x;
double y;
if (size == 2)
{
if (show_flag)
printPermutation(pmt, cnt);
x = 1.0;
for (int j = 0; j < dim; j++)
{
if (mat[j][pmt[j]] == 0) {
x = 0;
break;
}
x *= mat[j][pmt[j]];
}
det += ((cnt % 2) == 0) ? x : -x;
swap(pmt, 0, 1);
cnt++;
if (show_flag)
printPermutation(pmt, cnt);
x = 1.0;
for (int j = 0; j < dim; j++)
{
if (mat[j][pmt[j]] == 0) {
x = 0.0;
break;
}
x *= mat[j][pmt[j]];
}
det += ((cnt % 2) == 0) ? x : -x;
swap(pmt, 0, 1);
cnt--;
}
else if (size > 2)
{
doPermute(mat, dim, pmt, size - 1, cnt, det, show_flag);
for (int i = size - 2; i >= 0; i--)
{
swap(pmt, i, size - 1);
cnt++;
doPermute(mat, dim, pmt, size - 1, cnt, det, show_flag);
}
for (int i = 0; i <= size - 2; i++)
{
swap(pmt, i, size - 1);
cnt--;
}
}
}
int main(int argc, const char *argv[])
{
// vector<int> v = { 0, 1, 2, 3, 4 }; // syntax for C++11
vector<int> v(5);
for (int i = 0; i < 5; i++)
{
v[i] = i;
}
int counter = 0;
int dim = 3;
int n = 3;
double d = 0.0;
cout << "정사각행렬의 행의 수: ";
cin >> n;
// Allocate space for the vectors
Mat a;
Vec row(n);
cout << "행렬의 모든 요소를 입력하시오.\n";
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> row[j];
}
a.push_back(row);
}
cout << "\nA = \n";
printMatrix(a, 8);
if (n > 5)
{
for (int i = 5; i < n; i++)
{
v.push_back(i);
}
}
else if (n < 5) {
for (int i = 0; i < 5 - n; i++)
{
v.pop_back();
}
}
dim = n;
cout << endl;
bool show_flag = false; // true; // false;
doPermute(a, dim, v, n, counter, d, show_flag);
if (show_flag)
cout << endl;
cout << "A의 행렬식: det(A) = " << d << endl;
return 0;
}
/*
Execute & Output:
정사각행렬의 행의 수: 2
행렬의 모든 요소를 입력하시오.
7 8
9 2
A =
[[ 7 8 ]
[ 9 2 ]]
A의 행렬식: det(A) = -58
*/
'프로그래밍 > C++' 카테고리의 다른 글
c++0x 의 vector 타입과 for 반복문에 관하여 (0) | 2013.09.27 |
---|---|
Visual C++ 12와 cygwin64 의 g++로 테스트해 본 C++11 의 vector 타입 초기화 (0) | 2013.09.25 |
우순열 기순열을 이용하여 정사각행렬의 행렬식을 계산하는 C++ 언어 소스 (0) | 2013.09.20 |
지정한 개수의 모든 순열을 출력하는 C++ 언어 소스 (0) | 2013.09.20 |
이진 파일을 읽어서 16진수로 보여주는 HexView 소스 with C++ (0) | 2013.08.05 |