Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Python으로 구현하는 시공간 대수

기하 대수는 선형대수를 매우 멋지게 재정식화한 대안으로, 기하학적 변환과 물리 현상을 표현하는 간결한 체계를 제공합니다. 제가 가장 좋아하는 책 중 하나는 Leo Dorst, Daniel Fontijne, Stephen Mann이 쓴 *컴퓨터 과학을 위한 기하 대수(Geometric Algebra for Computer Science)*입니다. 이 책은 기하 대수를 시각화하는 매우 멋진 환경인 GAViewer라는 언어로 코드를 구현하지만, 저는 개념을 제대로 이해하기 위해 Python으로 직접 구현해 보고 싶었습니다.

  1. 블레이드(Blades): 기하 대수에서 방향이 있는 부분공간을 나타내는 기본 구성 요소입니다. 예를 들면 다음과 같습니다.
    • 스칼라(0-블레이드)는 점입니다.
    • 벡터(1-블레이드)는 방향이 있는 직선을 나타냅니다.
    • 바이벡터(2-블레이드)는 특정 방향으로 향한 평면 조각을 나타냅니다.
  2. 멀티벡터(Multivectors): 서로 다른 블레이드의 선형 결합이며, 다양한 기하학적 양을 나타낼 수 있습니다.

서로 다른 블레이드(스칼라, 벡터, 바이벡터)와 멀티벡터를 캡슐화하여 덧셈, 뺄셈, 기하곱 같은 연산을 할 수 있게 하는 클래스 구조를 만들겠습니다.

먼저 기본 블레이드 클래스를 정의해 봅시다.

import numpy as np

class Blade:
    def __add__(self, other):
        return Multivector([self, other])

    def __sub__(self, other):
        return Multivector([self, -other])

    def __neg__(self):
        return -1 * self  # Negation

class Scalar(Blade):
    def __init__(self, value):
        self.value = value

    def __repr__(self):
        return f"{self.value}"

class Vector(Blade):
    def __init__(self, components):
        self.components = np.array(components)

    def __repr__(self):
        return f"Vector({self.components})"

    def magnitude(self):
        return np.linalg.norm(self.components)

class Bivector(Blade):
    def __init__(self, vector1, vector2):
        self.vector1 = vector1
        self.vector2 = vector2

    def __repr__(self):
        return f"Bivector({self.vector1}, {self.vector2})"

Multivector 클래스는 블레이드의 임의의 선형 결합을 나타냅니다.

class Multivector:
    def __init__(self, blades=[]):
        self.blades = blades

    def __repr__(self):
        return f"Multivector({self.blades})"

    def add(self, other):
        self.blades.extend(other.blades)

    def scale(self, scalar):
        for blade in self.blades:
            blade.value *= scalar

벡터와 바이벡터에 대해 기하곱 같은 연산을 구현할 수 있습니다. Vector 클래스와 Bivector 클래스 안에 연산을 정의해 봅시다.

class Vector(Blade):
    def __init__(self, components):
        self.components = np.array(components)

    # Other methods as before...

    def __or__(self, other):
        """ Vector wedge product (bivector) """
        return Bivector(self, other)

    def __and__(self, other):
        """ Scalar product (dot product) """
        return Scalar(np.dot(self.components, other.components))


class Bivector(Blade):
    def __init__(self, vector1, vector2):
        self.vector1 = vector1
        self.vector2 = vector2

    def __repr__(self):
        return f"Bivector({self.vector1}, {self.vector2})"

    def dual(self):
        """ Returns the dual of a bivector as a vector """
        return Vector(np.cross(self.vector1.components, self.vector2.components))

이제 구현한 코드를 사용해 벡터 몇 개를 만들고, 그 곱을 계산하고, 기하 대수의 개념을 시연해 봅시다.

# Create instances of Scalars, Vectors, and Bivectors
s1 = Scalar(5)
v1 = Vector([1, 0, 0])
v2 = Vector([0, 1, 0])
biv = v1 | v2  # Wedge product (Bivector)

# Output representations
print("Scalar:", s1)
print("Vector 1:", v1)
print("Vector 2:", v2)
print("Bivector (v1 wedge v2):", biv)

# Vector dot product
dot_product = v1 & v2
print("Dot Product (v1 · v2):", dot_product)

# Vector wedge product to get a bivector
biv_product = v1 | v2
print("Wedge Product Bivector (v1 ∧ v2):", biv_product)

지금까지 다진 기반 위에서 구현을 시공간 대수(Space-Time Algebra, STA)로 확장할 수 있습니다. STA는 시간을 공간과 나란한 하나의 차원으로 통합하므로, 4차원 맥락(공간 3차원과 시간 1차원)에서 개체와 변환을 표현할 수 있습니다.

STA에서는 시간 벡터라는 개념을 도입하여 공간과 시간 모두에서 사건과 변환을 다룰 수 있습니다. 공간 성분과 시간 성분을 연관 짓기 위해 시간 단위를 정의하겠습니다(상대론적 맥락에서 일관성을 위해 흔히 광속인 로 나타냅니다).

Vector 클래스를 수정하여 시간을 하나의 성분으로 포함하도록 하고, 공간 3차원과 시간 1차원을 아우르는 SpaceTimeVector 클래스를 만들겠습니다.

class SpaceTimeVector(Blade):
    def __init__(self, components):
        # Expecting components in the form [x, y, z, t]
        assert len(components) == 4, "SpaceTimeVector must have four components: [x, y, z, t]."
        self.components = np.array(components)

    def __repr__(self):
        return f"SpaceTimeVector({self.components})"

    def magnitude(self):
        """ Calculate the Minkowski norm (using (-,+,+,+) signature) """
        return np.sqrt(-self.components[3]**2 + np.sum(self.components[:3]**2))

    def __add__(self, other):
        return SpaceTimeVector(self.components + other.components)

    def __sub__(self, other):
        return SpaceTimeVector(self.components - other.components)

    def __or__(self, other):
        """ Wedge product (resulting in a bivector in 3D + time) """
        return SpaceTimeBivector(self, other)

    def __and__(self, other):
        """ Scalar product (dot product, returns a scalar) """
        return Scalar(np.dot(self.components, other.components))

SpaceTimeBivector 클래스는 두 SpaceTimeVector 인스턴스의 기하곱을 나타냅니다.

class SpaceTimeBivector(Blade):
    def __init__(self, vector1, vector2):
        self.vector1 = vector1
        self.vector2 = vector2

    def __repr__(self):
        return f"SpaceTimeBivector({self.vector1}, {self.vector2})"

    def dual(self):
        """ Returns the dual of a bivector as a SpaceTimeVector """
        return SpaceTimeVector(np.cross(self.vector1.components[:3], self.vector2.components[:3]))

이제 SpaceTimeVector의 인스턴스를 만들고 기능을 시연해 봅시다.

# Create space-time vectors
st_vector1 = SpaceTimeVector([1, 2, 3, 4])  # (x, y, z, t)
st_vector2 = SpaceTimeVector([4, 5, 6, 7])  # (x', y', z', t')

print("Space-Time Vector 1:", st_vector1)
print("Space-Time Vector 2:", st_vector2)

st_vector_sum = st_vector1 + st_vector2
print("Sum of Space-Time Vectors:", st_vector_sum)

st_vector_diff = st_vector1 - st_vector2
print("Difference of Space-Time Vectors:", st_vector_diff)

dot_product_st = st_vector1 & st_vector2
print("Dot Product of Space-Time Vectors:", dot_product_st)

# Wedge product to get a space-time bivector
st_bivector = st_vector1 | st_vector2
print("Wedge Product Space-Time Bivector:", st_bivector)

magnitude = st_vector1.magnitude()
print("Magnitude of Space-Time Vector 1:", magnitude)

원문 © Stephen Diehl, stephendiehl.com · 글 CC BY-SA 4.0, 코드 MIT · Stephen Diehl은 런던의 소프트웨어 엔지니어이자 작가입니다(저자가 정한 소개 문구). 이 글은 저자가 개인 자격으로 쓴 것이며 어떤 조직과의 연관도 밝히거나 암시해서는 안 됩니다 (라이선스와 고지).
이 페이지는 원문을 한국어로 옮기며 변경한 비공식 번역이며 같은 CC BY-SA 4.0으로 제공합니다 · yeokja 한국어 번역 · Anthropic 사의 claude-opus-5-5 모델을 활용하여 번역되었으며 학습을 모두 비허용한 상태로 작업하였습니다.