정리 (정사각행렬의 행렬식, derterminant)
n × n 행렬
위에서 합은 집합
다음의 C++ 언어로 작성된 소스는 순열을 출력하는 소스를 수정아여 정사각행렬의 행렬식을 계산하도록 하였다.
컴파일은 g++ 또는 Visual C++ 의 명령줄 컴파일러 cl 을 이용한다.
// Filename: determinant-03.cpp
//
// Compile: g++ -std=c++11 -o determinant-03 determinant-03.cpp
// Execute: ./determinant-03 [integer]
//
// or
//
// Compile: cl /EHsc determinant-03.cpp
// Execute: determinant-03 [integer]
//
// Date: 2013. 9. 20.
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cstring>
using namespace std;
template<typename T>
class Array2D
{
private:
const int width;
T * data;
public:
T& operator() (int x, int y) { return data[y*width + x]; }
Array2D(const int w, const int h) : width(w) { data = new T[w*h]; }
~Array2D() { delete [] data; }
};
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 printMatrix(Array2D<double> &mat, int nrow, int ncol)
{
for (int i = 0; i < nrow; i++)
{
cout << "[[";
for (int j = 0; j < ncol; j++)
{
cout << " " << setw(9) << mat(i, j) << " ";
}
cout << " ]]" << endl;
}
cout << endl;
}
#include <sstream>
void readMatrix(Array2D<double> &mat, int nrow, int ncol)
{
std::string line;
double x;
int i = 0;
while (i < nrow*ncol)
{
cin >> line;
std::istringstream iss(line);
while (iss)
{
std::string sub;
iss >> sub;
std::istringstream ins(sub);
if (!(ins >> x))
break;
mat(i / ncol, i % ncol) = x;
i++;
}
}
}
void doPermute(Array2D<double> &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 k = 3;
double d = 0.0;
if (argc > 1)
{
sscanf(argv[1], "%d", &k);
}
if (k > 5)
{
for (int i = 5; i < k; i++)
{
v.push_back(i);
}
}
else if (k < 5) {
for (int i = 0; i < 5 - k; i++)
{
v.pop_back();
}
}
dim = k;
Array2D<double> mat(dim, dim);
cout << "Input a " << k << " by " << k << " matrix" << endl;
readMatrix(mat, k, k);
cout << endl;
cout << "The given matrix is " << endl;
printMatrix(mat, dim, dim);
bool show_flag = false;
doPermute(mat, dim, v, k, counter, d, show_flag);
if (show_flag)
cout << endl;
cout << "Its determinant is " << d << "." << endl;
return 0;
}
/*
Execute & Output:
명령프롬프트> determinant-03
Input a 3 by 3 matrix
1 2 3 4 5 6.02 7 8.1 9
The given matrix is
[[ 1 2 3 ]]
[[ 4 5 6.02 ]]
[[ 7 8.1 9 ]]
Its determinant is 0.718.
명령프롬프트> determinant-03 2
Input a 2 by 2 matrix
7 8
0.1 5.1
The given matrix is
[[ 7 8 ]]
[[ 0.1 5.1 ]]
Its determinant is 34.9.
명령프롬프트> determinant-03 4
Input a 4 by 4 matrix
1 2 3 4 5 6.02 7 8.1 9
0 0 0 7 0 2 3
The given matrix is
[[ 1 2 3 4 ]]
[[ 5 6.02 7 8.1 ]]
[[ 9 0 0 0 ]]
[[ 7 0 2 3 ]]
Its determinant is 32.22.
*/
'프로그래밍 > C++' 카테고리의 다른 글
Visual C++ 12와 cygwin64 의 g++로 테스트해 본 C++11 의 vector 타입 초기화 (0) | 2013.09.25 |
---|---|
vector 타입을 이용한 간단한 행렬 곱셈을 수행하고 행렬식을 구하는 C++ 언어 소스 (0) | 2013.09.20 |
지정한 개수의 모든 순열을 출력하는 C++ 언어 소스 (0) | 2013.09.20 |
이진 파일을 읽어서 16진수로 보여주는 HexView 소스 with C++ (0) | 2013.08.05 |
C++ 언어로 평방근, 입방근, n제곱근 구하는 함수를 구현하고 테스트하기 (0) | 2013.01.11 |