행렬 예제 프로그램

Posted by 쏘엔
2019. 3. 24. 03:36 DirectX 12/실습

행렬 예제 프로그램(소스).zip

이번에는 DirectXMath에 포함되어있는 행렬 함수들을 라이브러리를 사용하지 않고 직접 코딩해서 작성해보았다.

2개의 클래스가 있다.

첫 번째 MATRIX 클래스는 1개의 행렬을 내부적으로 double **형으로 저장해서 관리하는 클래스이고,

Matrix.h)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
    1개의 행렬을 double **형으로 관리하는 행렬 클래스이다.
    Matrix.h
*/
#pragma once
#include <iostream>
#include <stdarg.h>
using namespace std;
class MATRIX
{
private:
    int row, col;    // 이 행렬의 행과 열이다.
    double **matrix;    // 이 행렬의 원소를 가지게 되는 행렬 자체이다.
 
public:
    // 아무 인자없이 생성자로 생성하면 row와 col이 1로 초기화되어 할당된다.
    MATRIX()
    {
        row = col = 1;
        Allocator();
    }
 
    // 행과 열을 입력하여 생성하면 그에 맞는 크기로 할당된다.
    MATRIX(int _row, int _col) : row(_row), col(_col) { Allocator(); }
 
    // double ** 형을 입력하면 그것을 행렬로 간주하고 저장한다.
    MATRIX(double ** _matrix)
    {
        if (_matrix != nullptr)
            matrix = _matrix;
 
        else
            cout << "유효하지 않은 행렬을 입력했습니다. 행렬 생성 실패" << endl;
    }
 
    // double ** 형 + 행 갯수 + 열 갯수 생성자
    MATRIX(double ** _matrix, int _row, int _col)
    {
        if (_matrix != nullptr)
        {
            matrix = _matrix;
            row = _row;
            col = _col;
        }
 
        else
            cout << "유효하지 않은 행렬을 입력했습니다. 행렬 생성 실패" << endl;
    }
 
    void SetDemension(int _row, int _col);                // 행렬의 차원을 설정하는 메소드
    void Allocator();                                    // m x n의 행렬과 전치행렬을 동적할당하는 메소드
    void Deallocator();                                    // 동적할당을 해제하는 메소드(사용 후 반드시 호출해야함)
    void PrintMatrix();                                    // 행렬의 원소를 출력하는 메소드
    inline int GetRow(){return row;}                    // 행을 리턴하는 메소드
    inline int GetCol(){return col;};                    // 열을 리턴하는 메소드
    inline void SetRow(int _row){row = _row;}            // 행을 셋팅하는 메소드
    inline void SetCol(int _col){col = _col;}            // 열을 셋팅하는 메소드
    bool SetElements(int _args, ...);                    // 원소를 셋팅하는 메소드(총 갯수로 따짐)
    double ** GetMatrix();                                // 행렬을 얻음
    bool SetMatrix(double ** _matrix);                    // 행렬을 셋팅함
};
cs

Matrix.cpp)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
Matrix 클래스 정의
Matrix.cpp
*/
#include "Matrix.h"
 
void MATRIX::Allocator()
{
    if (matrix == nullptr)
    {
        // m x n의 배열을 메모리 동적할당
        matrix = new double*[row];
 
        for (int i = 0; i < row; i++)
        {
            matrix[i] = new double[col];
            memset(matrix[i], 0sizeof(double* col);
        }
    }
}
 
void MATRIX::Deallocator()
{
    if (matrix != nullptr)
    {
        // 메모리 동적할당 해제
        for (int i = 0; i < row; i++)
            delete[]matrix[i];
 
        delete[]matrix;
 
        matrix = nullptr;
    }
}
 
void MATRIX::PrintMatrix()
{
    // 할당이 되어있어야만 출력이 가능
    if (matrix != nullptr)
    {
        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                cout << matrix[i][j] << "\t";
            }
            cout << endl;
        }
        cout << endl;
    }
}
 
void MATRIX::SetDemension(int _row, int _col)
{
    // 할당된게 이미 있다면 할당을 해제한다.
    if (matrix != nullptr)
        Deallocator();
 
    // m, n 변수를 새로운 값으로 대체하고
    row = _row;
    col = _col;
 
    // 새롭게 할당한다.
    Allocator();
}
 
bool MATRIX::SetElements(int _args, ...)
{
    double arg;
    // 원소의 갯수와 행렬의 차원이 같아야함
    if (row * col != _args)
    {
        cout << "원소 입력 실패" << endl;
        return false;
    }
 
    va_list ap;    // 가변 인자용 변수 ap
    va_start(ap, _args);    // 첫 번째 가변인수를 가리키도록 셋팅
 
    for (int k = 0, i = 0, j = 0; k < _args; k++, j++)
    {
        // 해당 행의 열을 다 채우면 다음 행을 채워야함
        if (j == col)
        {
            j = 0;
            i++;
        }
 
        // 실제로 동적할당 배열에 저장
        arg = va_arg(ap, double);
        matrix[i][j] = arg;
    }
 
    va_end(ap);    // 뒷정리
 
    cout << "원소 입력 성공" << endl;
    return true;
}
 
double ** MATRIX::GetMatrix()
{
    return matrix;
}
 
bool MATRIX::SetMatrix(double ** _matrix)
{
    if (_matrix == nullptr)
        return false;
 
    else
    {
        matrix = _matrix;
        return true;
    }
}
 
cs


두 번째 MATRIX_MANAGER 클래스는 static 메소드의 집합 클래스로, 행렬 연산에 필요한 메소드를 제공하는 클래스이다.

MatrixManager.h)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
행렬에 관련된 메소드를 제공하는 클래스이다.(선언)
MatrixManager.h
*/
#pragma once
#include <iostream>
#include "Matrix.h"
#define FIX 0                // 행렬식 공식에서 고정되는 인덱스
#define ERROR_CODE -99999    // 행렬식 에러코드
 
// 2x2 소행렬의 행렬식을 구하는 매크로 함수
#define TwoByTwo(matrix) ( ( (matrix[0][0]) * (matrix[1][1]) ) - ( (matrix[0][1]) * (matrix[1][0]) ) );
 
using namespace std;
class MATRIX_MANGER
{
public:
    static double GetDeterminant(MATRIX _matrix);    // 4x4 이하의 행렬식을 구하는 메소드
    static MATRIX GetInverseMatrix(MATRIX _matrix);            // 역행렬을 구하는 메소드
    static MATRIX GetTransposeMatrix(MATRIX _matrix);            // 전치행렬을 만들고 리턴하는 메소드(MATRIX 클래스 버전)
    static double ** GetTransposeMatrix(double ** _matrix, int _row, int _col);            // 전치행렬을 만들고 리턴하는 메소드(double ** 버전) 사용 후에는 메모리 누수 방지를 위해 꼭 CustomDeallocator()를 사용해야한다.
    
    ////// 1번째인자:저장시킬 소행렬, 2번째:기준이 되는 원래 행렬식, 3번째:정방행렬 차원, 4번째:소거할 열
    static void GetMinorMatix(double **_minor, double **_matrix, int _n, int _removeRow, int _removeCol);    // 소행렬을 구하는 메소드
    static MATRIX GetMultiplyMatrix(MATRIX _m1, MATRIX _m2);        // 두 행렬의 곱을 리턴하는 메소드
    static MATRIX GetIdentity(int _demension);                    // 인자로 넘어온 차원의 단위행렬을 리턴하는 메소드
    static bool IsIdentity(MATRIX _matrix);                        // 단위 행렬인지
    static double ** CustomAllocator(int _row, int _col);        // 원하는 크기대로 동적할당시킬 메소드
    static void CustomDeallocator(double **_matrix, int _demension);    // 커스텀 동적할당 해제시킬 메소드
};
cs

 MatrixManager.cpp)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
/*
MatrixManager의 정의 (행렬에 필요한 메소드를 정의)
MatrixManager.cpp
*/
#include "MatrixManager.h"
 
MATRIX MATRIX_MANGER::GetTransposeMatrix(MATRIX _matrix)
{
    // 전치행렬은 원래 행렬의 행과 열의 갯수가 다르다.
    double ** transpose = MATRIX_MANGER::CustomAllocator(_matrix.GetCol(), _matrix.GetRow());
    double ** matrix = _matrix.GetMatrix();
 
    for (int i = 0; i < _matrix.GetRow(); i++)
    {
        for (int j = 0; j < _matrix.GetCol(); j++)
        {
            transpose[j][i] = matrix[i][j];    // 전치행렬은 원래행렬의 행과 열을 바꾼것과 같다.
        }
    }
 
    // 전치행렬은 행과 열이 바뀜에 주의하자
    MATRIX ret(transpose, _matrix.GetCol(), _matrix.GetRow());
    return ret;
}
 
double ** MATRIX_MANGER::GetTransposeMatrix(double ** _matrix, int _row, int _col)
{
    // 전치행렬은 원래 행렬의 행과 열의 갯수가 다르다.
    double ** transpose = MATRIX_MANGER::CustomAllocator(_col, _row);
 
    for (int i = 0; i < _row; i++)
    {
        for (int j = 0; j < _col; j++)
        {
            transpose[j][i] = _matrix[i][j];    // 전치행렬은 원래행렬의 행과 열을 바꾼것과 같다.
        }
    }
 
    return transpose;    // 사용 후에는 반드시 CustomDeallocator()를 사용해야함!
}
 
double MATRIX_MANGER::GetDeterminant(MATRIX _matrix)
{
    // 4x4를 초과하는 행렬은 허용하지 않는다
    if (_matrix.GetRow() != _matrix.GetCol() || (_matrix.GetRow() > 4))
        return ERROR_CODE;
 
    double det = 0;    // 실제 리턴할 행렬식 값
    switch (_matrix.GetRow())
    {
        // 2x2의 행렬식은 ad-bc로 정의된다.
    case 2:
        det = TwoByTwo(_matrix.GetMatrix());
        break;
 
        // 3x3의 행렬식은 재귀적으로 2x2행렬의 집합으로 이루어진다.
    case 3:
    {
        double **matrix = _matrix.GetMatrix();
        double **minor = nullptr;    // 소행렬
        bool sign = true;    // 부호는 +,-,+,-가 반복된다.
        double val = 0;
 
        for (int i = 0; i < _matrix.GetRow(); i++)
        {
            minor = CustomAllocator(22);    // 소행렬을 위해 2x2 크기로 동적할당
            GetMinorMatix(minor, matrix, _matrix.GetRow(), FIX, i);    // 소행렬을 얻어서 minor에 저장시킴
 
            val += (sign ? 1 : -1* matrix[FIX][i] * TwoByTwo(minor);    // 부호 곱하기 2x2행렬 공식인 ad-bc * 해당원소를 넣어주면 된다.
 
            // 아까 동적할당한 자원을 해제시킴
            if (minor != nullptr)
                CustomDeallocator(minor, 2);
 
            sign = !sign;    // 부호 스왑
        }
        det = val;
    }
    break;
 
    // 4x4를 초과하는 행렬은 가우스소거법 같은 방법이 더 효율적이다.
    case 4:
    {
        double **matrix = _matrix.GetMatrix();
        double **minor1 = nullptr;    // 3x3 행렬식
        double **minor2 = nullptr;    // 2x2 행렬식
        bool sign1 = true;    // 3x3행렬식의 부호는 +,-,+,-가 반복된다.
        bool sign2 = true;    // 2x2행렬식의 부호
 
        double val[4];// 각 소행렬의 값을 저장할 배열 (4x4행렬식은 4개의 3x3행렬식으로 이루어짐)
        memset(val, 0sizeof(double* 4);    // 값 초기화
 
        for (int i = 0; i < _matrix.GetRow(); i++, sign2 = true)
        {
            minor1 = CustomAllocator(33);    // 소행렬을 위해 3x3 크기로 동적할당
            GetMinorMatix(minor1, matrix, _matrix.GetRow(), FIX, i);    // 소행렬을 얻어서 minor1에 저장시킴
 
            for (int j = 0; j < _matrix.GetRow() - 1; j++)
            {
                // 방금 위에서 얻은 행렬식의 행렬식을 구한다(재귀적인 성질)
                minor2 = CustomAllocator(22);    // 소행렬을 위해 2x2 크기로 동적할당
                GetMinorMatix(minor2, minor1, _matrix.GetRow() - 1, FIX, j);
 
                val[i] += (sign2 ? 1 : -1* minor1[FIX][j] * TwoByTwo(minor2);    // 행렬식의 공식 적용
 
                sign2 = !sign2;    // 부호 스왑
 
                // 2x2 소행렬 할당 해제
                if (minor2 != nullptr)
                    CustomDeallocator(minor2, 2);
            }
 
            val[i] *= (sign1 ? 1 : -1* matrix[FIX][i];    // 3x3행렬식의 부호*해당원소의 값을 곱해서 방금 나온 값에 더해줌
 
            // 3x3 소행렬 할당 해제
            if (minor1 != nullptr)
                CustomDeallocator(minor1, 3);
 
            sign1 = !sign1;    // 부호 스왑
        }
 
        // 나온 값을 모~두 더해줌
        for (int i = 0; i < 4; i++)
            det += val[i];
    }
    break;
    }
 
    return det;    // 계산해서 나온 행렬식 리턴
}
 
void MATRIX_MANGER::GetMinorMatix(double **_minor, double **_matrix, int _n, int _removeRow, int _removeCol)
{
    // x=minor의 행, y=minor의 열
    int x, y;
    bool checker = false;    // 조건문에 들어갔는지 검사용
    x = y = 0;
 
    for (int i = 0; i < _n; i++)
    {
        // i행을 소거해야할 때는 그냥 무시
        if (i == _removeRow)
            continue;
 
        for (int j = 0; j < _n; j++)
        {
            // j열을 소거해야할 때에도 무시
            if (j == _removeCol)
                continue;
 
            // matrix의 실직적인 소행렬 minor를 저장함
            else
            {
                checker = true;
                _minor[x][y++= _matrix[i][j];
            }
        }
 
        // 소행렬을 다음 행, 첫 열로 이동
        if (checker == true)
        {
            x++;
            y = 0;
        }
    }
}
 
double ** MATRIX_MANGER::CustomAllocator(int _row, int _col)
{
    double ** matrix = nullptr;
 
    // m x n의 배열을 메모리 동적할당
    matrix = new double*[_row];
 
    for (int i = 0; i < _row; i++)
    {
        matrix[i] = new double[_col];
        memset(matrix[i], 0sizeof(double* _col);
    }
 
    return matrix;
}
 
void MATRIX_MANGER::CustomDeallocator(double **_matrix, int _demension)
{
    if (_matrix != nullptr)
    {
        // 메모리 동적할당 해제
        for (int i = 0; i < _demension; i++)
            delete[]_matrix[i];
 
        delete[]_matrix;
 
        _matrix = nullptr;
    }
}
 
MATRIX MATRIX_MANGER::GetInverseMatrix(MATRIX _matrix)
{
    // 역행렬은 정방행렬에만 있다.
    if (_matrix.GetRow() != _matrix.GetCol())
    {
        cout << "정방행렬이 아니므로 역행렬을 구할 수 없습니다." << endl;
        return NULL;
    }
 
    // 행렬식값이 0이면 특이행렬(역행렬이 없음)
    if (GetDeterminant(_matrix) == 0)
    {
        cout << "가역행렬이 아닙니다." << endl;
        return NULL;
    }
 
    // 4x4미만의 행렬만 역행렬을 구한다.
    if (_matrix.GetRow() > 4 || _matrix.GetCol() > 4)
    {
        cout << "4x4미만의 행렬만 가능합니다." << endl;
        return NULL;
    }
 
    double **inverse = CustomAllocator(_matrix.GetRow(), _matrix.GetCol());    // 일단 역행렬을 위한 할당
    double **minor = nullptr;    // 소행렬을 위한 배열
    double val = 0;        // 행렬식 값을 임시로 저장하기 위한 변수
    bool sign = true;    // 부호를 + - + - 로 활용하기 위한 변수
 
    // 행, 열의 갯수만큼 반복문을 돌려서
    for (int i = 0; i < _matrix.GetRow(); i++)
    {
        for (int j = 0; j < _matrix.GetCol(); j++)
        {
            minor = CustomAllocator(_matrix.GetRow() - 1, _matrix.GetCol() - 1);    // 소행렬을 위해 (row-1)x(col-1) 크기로 동적할당
            GetMinorMatix(minor, _matrix.GetMatrix(), _matrix.GetRow(), i, j);    // 소행렬을 얻어서 minor에 저장시킴(소거행열은 i,j)
 
            MATRIX sudDet(minor, _matrix.GetRow() - 1, _matrix.GetCol() - 1);    // 아까 얻은 소행렬을 MATRIX 인스턴스로 만듦
 
            // (i+1)+(j+1)가 (공식으로는 i+j이지만 인덱스는 0부터 시작하므로) 짝 수 이면 부호가 양수이고, 홀 수 이면 음수가 된다.
            if (((i + 1+ (j + 1)) % 2 == 0)
                sign = true;
 
            else
                sign = false;
 
            // 부호 * 소행렬의 행렬식값을 곱해준다
            val = (sign == true ? 1 : -1* GetDeterminant(sudDet);
 
            // 0에 마이너스 부호 붙는 것 방지
            if (val == 0.0)
                val = 0;
 
            inverse[i][j] = val;    // 이를 역행렬 배열에 저장한다.
 
            // 사용한 자원은 반납해야 메모리 누수가 없다.
            if (minor != nullptr)
                CustomDeallocator(minor, _matrix.GetRow() - 1);
        }
    }
 
    // 위에서 만든 여인수행렬을 전치행렬화 하여 딸림행렬로 만든다.(리턴값이 딸림행렬이다)
    inverse = MATRIX_MANGER::GetTransposeMatrix(inverse, _matrix.GetRow(), _matrix.GetCol());
 
    // 역행렬은 원래행렬의 행렬식(det) 값을 딸림행렬의 각 요소에 나눠주면 된다.
    double det = MATRIX_MANGER::GetDeterminant(_matrix);
    for (int i = 0; i < _matrix.GetRow(); i++)
        for (int j = 0; j < _matrix.GetCol(); j++)
            inverse[i][j] /= det;
 
    // 방금 만든 역행렬(double **형)을 MATRIX 인스턴스로 만들어서 리턴한다.
    MATRIX MatInverse(inverse, _matrix.GetRow(), _matrix.GetCol());
    return MatInverse;
}
 
MATRIX MATRIX_MANGER::GetMultiplyMatrix(MATRIX _m1, MATRIX _m2)
{
    // A행렬의 열의 갯수와 B행렬의 행의 갯수가 일치하지 않으면 곱셈은 성립하지 않는다.
    if (_m1.GetCol() != _m2.GetRow())
    {
        cout << "곱셈이 정의되지 않습니다." << endl;
        return NULL;
    }
 
    // 곱셈이 성립할 때 생성되는 행렬의 행과 열의 수
    int row = _m1.GetRow();
    int col = _m2.GetCol();
 
    double **mat1 = _m1.GetMatrix();    // 행렬 A의 double **형
    double **mat2 = _m2.GetMatrix();    // 행렬 B의 double **형
    double **ret = MATRIX_MANGER::CustomAllocator(row, col);    // 곱셈으로 생성되는 행렬은 (A의 행 x B의 열) 차원이다.
 
    double val = .0;    // 곱한 결과를 저장할 변수
    int x, y;            // 결과 행렬의 인덱스
    x = y = 0;
 
    // 행렬의 곱 순서대로 곱한 결과를 ret에 저장한다.
    // A = m x n,    B = n x p 일 때, C = m x p 와 같다.
    for (int i = 0, k = 0; i < _m1.GetRow(); k++, val = 0)
    {
        for (int j = 0; j < _m2.GetRow(); j++)
        {
            val += mat1[i][j] * mat2[j][k];        // 곱한 결과를 저장해둔다.
        }
 
        // 곱한 결과를 C(결과)행렬에 저장하고, 다음 인덱스를 넘어가야하면 조건에 맞게 처리한다.
        ret[x][y++= val;
        if (y == col)
        {
            x++;        // 다음 행
            y = 0;        // 첫 열로
 
 
            k = -1;    // B는 다시 처음처럼 곱셈을 해야하므로(바로 for문 조건으로 인해 1 증가하므로 -1이다)
            i++;    // A를 다음 행으로
        }
    }
 
    // 결과를 MATRIX로 만들어 리턴
    MATRIX matRet(ret, row, col);
    return matRet;
}
 
MATRIX MATRIX_MANGER::GetIdentity(int _demension)
{
    // 파라미터 차원의 행렬을 생성한다.
    double **ret = CustomAllocator(_demension, _demension);
 
    // 단위행렬을 만들고
    for (int i = 0; i < _demension; i++)
        ret[i][i] = 1.0;
 
    // 리턴한다.
    MATRIX matRet(ret, _demension, _demension);
    return matRet;
}
 
bool MATRIX_MANGER::IsIdentity(MATRIX _matrix)
{
    if (_matrix.GetRow() != _matrix.GetCol())
        return false;
 
    double **matrix = _matrix.GetMatrix();
 
    for (int i = 0; i < _matrix.GetRow(); i++)
    {
        for (int j = 0; j < _matrix.GetCol(); j++)
        {
            // main diagonal일 때 1이 아니면 단위행렬이 아니다.
            if (i == j)
            {
                if (matrix[i][j] != 1)
                    return false;
 
                else
                    continue;
            }
 
            // 그 외에는 모두 0이어야 한다.
            if (matrix[i][j] != 0)
                return false;
        }
    }
 
    return true;
}
cs



main 함수에서 행렬을 설정하고, 단위행렬을 얻고, 곱셈, 전치행렬, 행렬식, 역행렬 등을 구한다.

main.cpp)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*
행렬 예제 프로그램
main.cpp
*/
 
#include <iostream>
#include "MatrixManager.h"
#include "Matrix.h"
using namespace std;
 
int main()
{
    MATRIX A(44);        // 4x4 크기의 행렬 A를 생성한다.
 
    // 원소를 채운다.
    A.SetElements(16,
        1.00.00.00.0,
        0.02.00.00.0,
        0.00.04.00.0,
        1.02.03.01.0);
 
    MATRIX B = MATRIX_MANGER::GetIdentity(A.GetRow());        // 단위 행렬을 얻는다.
 
    MATRIX C = MATRIX_MANGER::GetMultiplyMatrix(A, B);        // A와 B를 곱해서 나온 결과 행렬을 C에 저장한다.
 
    MATRIX D = MATRIX_MANGER::GetTransposeMatrix(A);        // A행렬의 전치행렬을 얻어서 D에 저장한다.
 
    double det = MATRIX_MANGER::GetDeterminant(A);            // A의 행렬식을 구해서 det에 저장한다.
    MATRIX E = MATRIX_MANGER::GetInverseMatrix(A);            // A의 역행렬을 구해서 E에 저장한다.
 
    MATRIX F = MATRIX_MANGER::GetMultiplyMatrix(A, E);        // A와 E를 곱한다.
 
    // 연산 결과를 출력한다.
    cout << "A = " << endl;
    A.PrintMatrix();
    cout << endl;
 
    cout << "B = " << endl;
    B.PrintMatrix();
    cout << endl;
 
    cout << "C = A*B = " << endl;
    C.PrintMatrix();
    cout << endl;
 
    cout << "D = transpose(A) = " << endl;
    D.PrintMatrix();
    cout << endl;
 
    cout << "det = determinant(A) = " << det << endl << endl;
 
    cout << "E = inverse(A) = " << endl;
    E.PrintMatrix();
    cout << endl;
 
    cout << "F = A*E = " << endl;
    F.PrintMatrix();
    cout << endl;
 
    // 메모리를 반납한다.
    A.Deallocator();
    B.Deallocator();
    C.Deallocator();
    D.Deallocator();
    E.Deallocator();
    F.Deallocator();
    return 0;
}
cs


실행화면)




원리를 생각하면서 한 번이라도 코딩해보는게 많은 도움이 되는 것 같다.


잘못된 점은 따끔히 지적해주시고, 더 좋은 의견이 있으시면 언제든지 덧글로 남겨주세요.