koodev

'전체 글'에 해당되는 글 75건

  1. Group - Law of composition
  2. Group
  3. Unsigned Integer to String with Generics

Group - Law of composition

Math

어떤 집합 S의 law of composition을 다음과 같이 정의해보자. 일단 집합 S에서 두 원소 a,b를 뽑는다. 그다음 그 둘을 조합해서 집합 S내의 다른 원소 p로 만든다고 하자.

위의 law of composition을 함수로 생각해보면, 이 함수는 S의 원소 두개를 인자로 받아서 S의 원소 하나로 출력한다. 일종의 map 과 같은 것이다.

S × S → S
a,b ↝ p.

여기서 S × S 는 집합 S내의 원소 pair (a, b)의 product를 의미한다.

p = f(a, b)와 같은 functional notiation 은 불편해서 잘 쓰이지 않는다. 대신 law of composition의 종류 혹은 성질에 따라 아래와 같이 덧셈이나 곱셈 등의 많이 쓰인다.

p = ab, a × b, a ◦ b, a + b, and so on.

그리고 a와 b를 composition 한 것이 곱셈의 성질을 갖는다면 이걸 product 라고 부를 것이고, 덧셈의 성질을 가질 경우 sum 이라고 부를 것이다.

그러면 n × n matrix 들의 집합에서 law of composition이 matrix multiplication 인 Group을 예로 들어 자세히 살펴보자.

Group에서 중요한 사실 중 하나는 S의 두 원소 a와 b를 composition한 결과인 ab가 역시 S의 원소라는 점이다. 예를 들어 a =  

13
02
  , b =  
10
21
  라면 이 둘의 product인 ab는  
73
42
  가 된다. 그리고 product 연산이 이루어져서 일단 ab가 되고 나면 다시는 원래 원소였던 a와 b로 복구할 수 없게된다.

law of composition에는 associativecommutative 라는 특성이 있을 수 있다. associative는 아래와 같은 결합법칙을 의미한다.

(ab)c = a(bc)

그리고 commutative는 아래와 같이 교환법칙을 말한다.

ab = ba

matrix multiplication이 law of composition인 경우에는 associative 하지만 commutative 하지는 않다. 반면, 정수집합에서 덧셈이 law of composition인 경우에는(ℤ+) commutative 까지 가능하다. 때문에 보통 associative 한 Group에서 composition을 표기할 경우 곱셈 방식으로 표기하고(commutative 여부는 관심없음), commutative 까지 한 경우는 덧셈 방식으로 표기한다.

일반적으로 associative 한지 여부가 commutative 한지 여부보다 더 근본적으로 중요하게 여겨진다. 그 근거 중에 하나는 composition이 여러개의 함수들인 경우 이들 함수들을 조합하여 하나의 함수로 나타낼 수 있기 때문이다.

예를 들어 집합 T가 있고 T에서 T로 가는(T를 입력으로 받고 T를 내놓는) 함수 g와 f가 있다고 하자. 그리고 g ◦ f 를 조합된 map, t ↝ g(f(t)) 를 나타낸다고 하자. 그리고 S를 T에서 T로 가는 매핑들의 집합이라고 한다면(S = Maps(T,T)), 하나로 조합된 g ◦ f 이 모든 S의 경우에 대해서 law of composition이 될 수가 있다. 함수 레벨에서 하나로 합쳐써도 된다는 이야기다.

다시 단순한 예를 들어보자. 집합 T가 두 원소 a와 b를 가질 때 T에서 T로 가는 매핑의 종류는 모두 네 가지가 된다.

  • i: the identity map defined by i(a) = a, i(b) = b;
  • 𝜏: the transposition, defined by 𝜏(a) = b, 𝜏(b) = a;
  • α: the constant function α(a) = α(b) = a;
  • β: the constant function β(a) = β(b) = b.

이들 중 두개를 조합하여 하나의 law of composition을 만든다고 해 보면 그 경우들은 아래와 같이 multiplication table로 나타낼 수 있다.

그리고 이들 중 임의의 2개의 조합의 결과는 아래와 같이 보면 된다.

여기서 𝜏 ◦ α = β 인데 순서를 뒤바꾼 α ◦ 𝜏 = α 이다. 이걸 보면 함수들의 composition은 commutative 하지 않음을 알 수 있다.

방금전 살펴본 2개 함수 조합의 associative를 보다 일반적인 n개를 조합하는 경우로 확장하여 생각해보자.

a1a2...an = ?

이들을 어떻게 조합하여 하나의 연산으로 만들 수 있을까? 우선 익숙한 방법인 왼쪽부터 두 개씩 짝을지어 차근차근 조합해 나가는 경우가 있을 수 있다.

((a1a2)a3)a4 ...

만일 n=4 라면 위와 같은 경우를 포함해서 4가지 조합 방법이 있을 수 있다. 예를 들면 (a1a2)(a3a4) 같은. 그런데 만일 composition 연산이 associative 하다면 이 모든 경우의 함수 조합이 결과적으로는 동일하게 된다(induction으로 증명할 수 있는데 생략한다).

'Math' 카테고리의 다른 글

Symmetric Group  (0) 2017.05.08
Abelian Group  (0) 2017.05.08
Group  (0) 2017.04.28
크래머의 법칙 정리  (0) 2017.03.19
증명(proof) 관련 용어 정리  (0) 2017.02.02

Group

Math

정리를 안하니 계속 잊어먹게 된다. Artin Algebra에서 설명하는 Group 에 대해서 정리해본다.

Group을 한마디로 정의하면, 'law of composition 이 정의되어 있고 각 엘리먼트들은 그 안에서 inverse를 갖는 집합'이다. 책에서 사용하는 정의는 아래와 같다.

Definition. A group is a set G together with a law of composition which is associative and has an identityt element, and such that every element of G has an inverse.

예를 들어 0이 아닌 실수의 집합을 생각해보자. 이 집합의 law of composition을 곱셈이라고 정의하면, 각 원소 k의 inverse는 1/k가 된다. 따라서 이 집합과 law of composition은 Group이 될 수 있으며 수학책에서 보통 ℝ× 로 표기한다.

[A sumbol of the set of real numbers]

다른 예를 들면, 모든 실수의 집합에서 law of composition을 덧셈으로 정의해도 Group으로 만들 수 있다. 이 경우 각 원소 k의 inverse는 -k가 된다. 그리고 이 Group은 ℝ+ 으로 표기한다.

책에서 특히 중요하다고 소개하는 Group이 있는데, invertible 한 n × n matrix들의 집합으로서 law of composition이 matrix multiplication인 'General Linear Group' ‐ GLn 이다. 따라서 GLn은 아래와 같이 표기할 수 있다.

GLn = { n × n matrices A with det A ≠ 0 }.

'Math' 카테고리의 다른 글

Symmetric Group  (0) 2017.05.08
Abelian Group  (0) 2017.05.08
Group - Law of composition  (0) 2017.04.28
크래머의 법칙 정리  (0) 2017.03.19
증명(proof) 관련 용어 정리  (0) 2017.02.02

Unsigned Integer to String with Generics

Programming

Swift를 사용해서 부호없는 십진수를 십육진수 형태의 문자열로 바꾸는 Generics 함수를 작성한 내용을 기록한다.

Swift의 포인터를 공부하다가 십진수를 십육진수로 바꾸어 1바이트 단위로 보는 기능이 필요했다. 인터넷을 참고하여 String 클래스의 메소드를 사용하면 Decimal을 Hex로 바꿀 수 있었다.

http://stackoverflow.com/questions/24229505/how-to-convert-an-int-to-hex-string-in-swift

let dec = 10
let hex = String(dec, radix:16)
print("0x\(hex)") // 0xa

그런데 매번 이렇게 정수를 문자열로 바꾸어주는 표현식을 적기가 귀찮아서 함수로 만들어 보기로 했다.

func toHex(_ num: Int) -> String {
    let hex = String(num, radix: 16)
    return "0x\(hex)"
}

let dec = 10
print("\(toHex(dec))") // 0xa

이 함수를 가지고 아래와 같이 1바이트 부호없는 정수와 8바이트 부호없는 정수의 값을 찍어보았다. 당연히 타입이 안 맞으니 에러가 나왔다.

let uint8Pointer = UnsafeMutablePointer<UInt8>.allocate(capacity: 8)
uint8Pointer.initialize(from: [0x37, 0x77, 0x11, 0x11, 0x02, 0x33, 0x39, 0x00])

let uint64Pointer = UnsafeMutableRawPointer(uint8Pointer).bindMemory(to: UInt64.self, capacity: 1)

let rawPointer = UnsafeMutableRawPointer(uint64Pointer)
var fullInteger = rawPointer.load(as: UInt64.self)
var firstByte = rawPointer.load(as: UInt8.self)

func toHex(_ num: UInt64) -> String {
    let hex = String(num, radix: 16)
    return "0x\(hex)"
}

print("8byte: \(toHex(fullInteger))")
print("1byte: \(toHex(firstByte))")

./pointer_test3.swift:22:23: error: cannot convert value of type 'UInt64' to expected argument type 'Int'
print("8byte: \(toHex(fullInteger))")
                      ^~~~~~~~~~~
                      Int(       )
./pointer_test3.swift:23:23: error: cannot convert value of type 'UInt8' to expected argument type 'Int'
print("1byte: \(toHex(firstByte))")
                      ^~~~~~~~~
                      Int(     )

그럼 타입을 맞춰주면 된다. 전달인자 목록의 Int 대신에 UInt를 넣어서 다시 해본다. 그렇지만 역시 에러가 나온다. UInt가 내부적으로 4바이트이면 UInt8, UInt64 어느 쪽과도 타입이 맞지 않는다. 그러면 타입을 맞추기 위해 함수를 2개 만들어야 할까? 2바이트, 4바이트 데이터에 대응하기 위해서는 4개를 만들어야 한다.

코드중복 문제를 해결하기 위해 Generics 라는걸 써보기로 했다. 'Generics는 C++ 템플릿 비슷한 것이니 전달인자 타입을 대충 T로 우겨 넣고 컴파일하면 되겠지'라고 생각하고 함수를 다시 작성해 보았다.

func toHex<T>(_ num: T) -> String {
    let hex = String(num, radix: 16)
    return "0x\(hex)"
}

./pointer_test3.swift:18:15: error: cannot invoke initializer for type 'String' with an argument list of type '(T, radix: Int)'
    let hex = String(num, radix: 16)

./pointer_test3.swift:18:15: note: expected an argument list of type '(T, radix: Int, uppercase: Bool)'
    let hex = String(num, radix: 16)

이번에는 String 클래스의 생성자가 동작을 안했다. 함수 밖에서와 같은 내용일텐데 함수 안에서는 제대로 동작하지 않는 걸까? Swift의 Generics는 C++의 템플릿과는 달리 타입 체킹을 더 엄격히 할 수 있다고 한다. T로 정의된 타입이 들어와도 이게 String 클래스의 생성자에 정의된 제약 조건에 의해서 아무 T나 받지 못하게 되어 있던 것이다.

https://developer.apple.com/reference/swift/string/1641688-init

String 클래스의 해당 생성자 문서를 보면 메소드가 아래와 같이 where로 지정된 제약 조건이 걸려 있다.

init<T>(_ value: T, radix: Int = default, uppercase: Bool = default) where T : UnsignedInteger

즉, T 타입은 아무 타입이 아니라 UnsignedInteger 여야 하는 것이다. 따라서 toHex 함수에도 똑같이 제약 조건을 달아주어야 한다.

func toHex<T>(_ num: T) -> String where T : UnsignedInteger {
    let hex = String(num, radix: 16)
    return "0x\(hex)"
}

print("8byte: \(toHex(fullInteger))") // 8byte: 0x39330211117737
print("1byte: \(toHex(firstByte))") // 1byte: 0x37

그러면 부호있는 정수를 Hex로 바꾸려면 어떻게 해야할까? 아쉽게도 이 경우는 함수를 하나 더 작성해야 한다. UnsignedInteger를 _SignedInteger 라는 제약 조건으로 대체하여 같은 함수를 하나 더 만들면 된다. String 생성자도 이런 코드 중복이 보인다. 어쩔 수 없는 듯.

https://developer.apple.com/reference/swift/string/1640980-init

'Programming' 카테고리의 다른 글

macOS에 emacs ggtags 설치 및 설정  (0) 2017.10.17
Xcode에 assimp 올리기  (0) 2017.06.06
OpenGL로 원 그리기  (1) 2017.05.27
Swift3 - result unused warning 없애기  (0) 2017.05.23
Swift - 튜플에 포인터로 접근하기  (0) 2017.05.14