본문 바로가기
text/Go

벡터 곱셉 (inner, cross, outer product) with Go

by hoonzii 2022. 10. 22.
반응형

벡터의 내적 (inner product)

\( a \cdot b \) 로 적는다.

  1. 벡터의 크기(norm)
    → ||[3,4]|| → 5 = \( \sqrt{3^2+4^2} \)
    → ||a|| → \( \sqrt{a_0^2+a_1^2...+a_n^2} \)
  2. 벡터의 크기를 곱한뒤 사이각\( (\theta) \)의 \( \cos \) 한 값을 곱해준다. \( ||a|| * ||b|| * cos(\theta) \)
  3. 그래서 왜 내적이 저런 공식으로 나온 건지
    → 벡터 b의 입장에서 a가 움직인 거리는 ||a|| * \( \cos(\theta) \) 만큼 움직이고 b 세계의 단위인 ||b||를 곱해준 값
     벡터에는 방향이 있으므로, 방향이 일치하는 만큼만 곱한다. 
    -> 직교하면 \( cos(\theta) = 0\), 고로 값은 항상 0

출처 : https://wikidocs.net/22384

 

  1. 더 쉽게 계산 가능 
    각 요소들끼리 곱의 합
    → \( \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)
}

결과

1*2 + 2*3 + 3*4 = 2+6+12 = 20 으로 제대로 계산된 걸 확인 할 수 있다.

그럼 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) \)

출처 :  https://www.mathsisfun.com/algebra/vectors-cross-product.html

→ 쉬운 공식으로는 (사잇각을 모를 때)

출처 :  http://www.gisdeveloper.co.kr/?p=809

 

//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 \) 로 적는다.

→ 두 벡터 간의 텐서 곱을 의미 (결괏값으로 스칼라나 벡터가 아닌 행렬 도출)

출처 : https://namu.wiki/w/외적

//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?

 

What is a concise way to create a 2D slice in Go?

I am learning Go by going through A Tour of Go. One of the exercises there asks me to create a 2D slice of dy rows and dx columns containing uint8. My current approach, which works, is this: a:= ma...

stackoverflow.com

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차원도 가능하다고 한다! (알고 싶지 않다!)

출처 : https://namu.wiki/w/외적

 

반응형

'text > Go' 카테고리의 다른 글

VScode 에서 Go 한글 print가 안되서 한 삽질 적어놓기  (0) 2022.10.12

댓글