10.13

신승빈·2022년 10월 13일
0

KGCA 수업

목록 보기
49/128
post-thumbnail

행렬

행렬표현:[n×m]행렬 표현 : [n \times m] 행렬식:n×m행렬식 : |n \times m|

행렬의 곱

행 벡터와 열 벡터의 내적
단위행렬을 제외한 모든 행렬의 곱은 교환법칙이 성립하지 않음

행렬의 곱 알고리즘

슈트라센 알고리즘 : https://ko.wikipedia.org/wiki/%EC%8A%88%ED%8A%B8%EB%9D%BC%EC%84%BC_%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98
딥마인드 알고리즘 : https://www.deepmind.com/blog/discovering-novel-algorithms-with-alphatensor
슈트라센 알고리즘보다 더 빠르다고 한다는데 계산식은 찾아봐야 할 듯

전치행렬(Transpose)

ATA^T
주대각선을 기준으로 반사 대칭하여 얻은 행렬
(AB)T=BTAT(AB)^T = B^TA^T

역행렬(Inverse)

A-1
정사각행렬 A에 대하여 AX=XA=IAX = XA = I 인 행렬
(A-1)T = (AT)-1
(AB)-1 = B-1A-1
A-1 = 1det(A)\frac{1}{det(A)}Aadj
수반행렬 Aadj = 여인수 행렬의 전치행렬
A행렬이 직교행렬일 경우 A-1 = AT를 통해 연산량을 크게 줄일 수 있음

행렬식(Determinant)

역행렬 존재 여부 결정, det(A)=0det(A) = 0이면 역행렬 존재하지 않음

표기법

성질

계산법

사루스 법칙, 소행렬식 전개(라플라스 전개) 등 존재

Reference : https://namu.wiki/w/%ED%96%89%EB%A0%AC%EC%8B%9D#s-8.1
Reference : https://namu.wiki/w/%EB%9D%BC%ED%94%8C%EB%9D%BC%EC%8A%A4%20%EC%A0%84%EA%B0%9C
소행렬식

원소의 소행렬식을 이용해 minor 행렬 구성
소행렬식의 여인수 행렬 구성
원행렬의 임의의 벡터와 소행렬식의 여인수 행렬을 이용해 Det계산

변환(Transform)


회전 방향 사진 추가 필요
위 변환 공식은 Vector가 행렬 뒤에 붙는 경우로 Vector가 Matrix앞에 붙을 경우 sin함수의 계수가 바뀐다
DirextX는 행우선 저장방식이므로 Vector-Matrix방식으로 연산이 수행되야 한다
기본적으로 y축은 다른 축과 sin함수의 계수가 다른 것을 확인할 수 있음

실차원과 행렬차원

행렬차원은 계산하고자 하는 실 차원의 크기보다 1차수 더 커야한다
2차원을 예를들어 2차원에서 회전과 신축은 2차원 벡터와 차수가 같은 22 행렬로 계산이 가능하지만, 이동의 경우 22 행렬로는 표현이 불가능
하지만 3*3행렬로 표현할 경우 추가된 벡터에 dx를 추가하므로써 이동 역시 행렬곱을 통해 계산이 가능

이를 통해 Vector의 회전, 신축, 이동을 모두 행렬의 곱으로 표현할 수 있게 되었고, 변환 행렬을 미리 수행하여 마지막에 Vector들에 적용하는 방식으로 연산량을 크게 줄일 수 있게 됨
이를 동차좌표계라고 하는데 아핀변환과의 차이가 무엇일까?

독특한 struct union 구조

#include <iostream>

using namespace std;

struct float2
{
    union
    {
        struct
        {
            float x;
            float y;
        };
        float f[2];
    };
};

struct float3 : public float2
{
    union
    {
        struct
        {
            float z;
        };
    };
    float f[3];					// 메모리 따로 할당 됨
};

int main()
{
    float2 f2;
    f2.x = 10;
    f2.y = 10;
    //f2.f[2] = 50;				// 접근 불가능
    //cout << f2.f[3] << endl;	// 접근 가능. 위험한 접근

    float3 f3;
    f3.x = 10;
    f3.y = 20;
    f3.z = 30;
    f3.f[2] = 50;
    //f3.f[3] = 60;				// 접근 불가능
    cout << f3.x << ", " << f3.y << ", " << f3.z << endl;
    cout << f3.f[0] << ", " << f3.f[1] << ", " << f3.f[2] << endl;
    //cout << f3.f[3] << endl;	// 접근 가능. 위험한 접근
    cout << sizeof(float3) << endl;		// memory size 24

    return 0;
}
#include <iostream>

using namespace std;

struct float2
{
    union
    {
        struct
        {
            float x;
            float y;
        };
        float f[2];
    };
};

struct float3 : public float2
{
    union
    {
        struct
        {
            float z;
        };
    };
};

int main()
{
    float2 f2;
    f2.x = 10;
    f2.y = 10;

    float3 f3;
    f3.x = 10;
    f3.y = 20;
    f3.z = 30;
    f3.f[2] = 50;
    cout << f3.x << ", " << f3.y << ", " << f3.z << endl;
    cout << f3.f[0] << ", " << f3.f[1] << ", " << f3.f[2] << endl;	// 기대되로 모두 접근 가능
    cout << sizeof(float3) << endl;

    return 0;
}
profile
이상을 길잡이 삼아 로망을 추구합니다.

0개의 댓글