벡터의 내적 (inner product)
\( a \cdot b \) 로 적는다.
- 벡터의 크기(norm)
→ ||[3,4]|| → 5 = \( \sqrt{3^2+4^2} \)
→ ||a|| → \( \sqrt{a_0^2+a_1^2...+a_n^2} \) - 벡터의 크기를 곱한뒤 사이각\( (\theta) \)의 \( \cos \) 한 값을 곱해준다. \( ||a|| * ||b|| * cos(\theta) \)
- 그래서 왜 내적이 저런 공식으로 나온 건지
→ 벡터 b의 입장에서 a가 움직인 거리는 ||a|| * \( \cos(\theta) \) 만큼 움직이고 b 세계의 단위인 ||b||를 곱해준 값
→ 벡터에는 방향이 있으므로, 방향이 일치하는 만큼만 곱한다.
-> 직교하면 \( cos(\theta) = 0\), 고로 값은 항상 0
- 더 쉽게 계산 가능
각 요소들끼리 곱의 합
→ \( \overrightarrow{a} \cdot \overrightarrow{b} = a_1b_1+a_2b_2 + ... + a_nb_n \)
// product.go
package linalgexample
import (
"errors"
)
var notCalculateErr = errors.New("not calculate") // 벡터의 크기가 다르면 계산 불가
func InnerProduct(vector_a []int, vector_b []int) (int, error) {
if len(vector_a) != len(vector_b) {
return 0, notCalculateErr
}
scalar := 0
for i, _ := range vector_a {
scalar += vector_a[i] * vector_b[i]
}
return scalar, nil
}
product.go의 함수를 불러와 실행하는 main.go
//main.go
package main
import (
"fmt"
"log"
linalgexample "linalgexample filePath"
)
func main() {
vector_a := [3]int{1, 2, 3}
vector_b := [3]int{2, 3, 4}
inner, err := linalgexample.InnerProduct(vector_a[:], vector_b[:])
if err != nil {
log.Fatalln(err)
}
fmt.Println(inner)
}
결과
그럼 vector_b의 크기를 4로 바꾼 뒤, 계산시에 err 발생 되는지 확인
func main() {
vector_a := [3]int{1, 2, 3}
vector_b := [4]int{2, 3, 4, 5}
inner, err := linalgexample.InnerProduct(vector_a[:], vector_b[:])
if err != nil {
log.Fatalln(err)
}
fmt.Println(inner)
}
결과
벡터의 외적 (cross product)
\( x×y \) 로 적는다.
벡터의 크기에 사잇각 \( \theta \) 의 \( sin \) 한 값을 곱해준다.
→ \(||a||*||b||*sin(\theta) \)
→ 밑변을 \( \overrightarrow{a} \), 높이를 \( \overrightarrow{b}*sin(\theta) \) 로 하는 평행사변형의 넓이 크기의 벡터를 반환!
→ 해당 벡터는 \( \overrightarrow{a}, \overrightarrow{b} \) 와 수직을 이룬다.
- 주의점! 벡터의 차원수는 무조건 3인 경우만 가능 \( (=R^3) \)
→ 쉬운 공식으로는 (사잇각을 모를 때)
//product.go
// cross product 의 경우, 차원수는 3으로 고정!
func CrossProduct(vector_a [3]int, vector_b [3]int) ([3]int, error) {
vector := [3]int{0, 0, 0}
vector[0] = vector_a[1]*vector_b[2] - vector_a[2]*vector_b[1]
vector[1] = vector_a[2]*vector_b[0] - vector_a[0]*vector_b[2]
vector[2] = vector_a[0]*vector_b[2] - vector_a[2]*vector_b[0]
return vector, nil
}
product.go의 함수를 불러와 실행하는 main.go
//main.go
func main() {
vector_a := [3]int{1, 2, 3}
vector_b := [3]int{2, 3, 4}
cross, err := linalgexample.CrossProduct(vector_a, vector_b)
if err != nil {
log.Fatalln(err)
}
fmt.Println(cross)
}
실행 결과
벡터의 외적 (outer product)
\( a \bigotimes b \) 로 적는다.
→ 두 벡터 간의 텐서 곱을 의미 (결괏값으로 스칼라나 벡터가 아닌 행렬 도출)
//product.go
func OuterProduct(vector_a []int, vector_b []int) [][]int {
// 둘이 크기가 달라도 성립
matrix := make([][]int, len(vector_a))
for i := 0; i < len(vector_a); i++ {
matrix[i] = make([]int, len(vector_b))
}
for i, a := range vector_a {
for j, b := range vector_b {
matrix[i][j] = a * b
}
}
return matrix
}
//main.go
func main() {
vector_a := [3]int{1, 2, 3}
vector_b := [3]int{2, 3, 4}
matrix := linalgexample.OuterProduct(vector_a[:], vector_b[:])
fmt.Println(matrix)
}
실행 결과
참고
- 행렬의 할당
행렬의 경우, 벡터와 다르게 2차원으로 공간을 할당& 초기화해줘야 함
처음 시도한 건
matrix := [len(vector_a)][len(vector_b)] int {}
였는데, 크기 설정은 constant 한 값만 가능하다고 에러가 났었다.
그래서 참고 한글
What is a concise way to create a 2D slice in Go?
golang의 make 함수를 통해 초기화해준다.
matrix := make([][]int, len(vector_a))
for i := 0; i < len(vector_a); i++ {
matrix[i] = make([]int, len(vector_b))
}
- 외적 (cross product)의 곱셈 가능 차원
벡터의 외적(cross product) 의 경우,
3차원만 가능하다고 적어 놨는데 나무 위키에 따르면 7차원도 가능하다고 한다! (알고 싶지 않다!)
'text > Go' 카테고리의 다른 글
VScode 에서 Go 한글 print가 안되서 한 삽질 적어놓기 (0) | 2022.10.12 |
---|
댓글