2023년 9월 23일 토요일

python pybind 11 c++ 과 연결하기

pybind 라는 패키지가 있다.

c++과 연결하는 것인데, header only library이고,

아래 페이지가 해당 사이트이다. 
https://github.com/pybind/pybind11

기존에는 ctype등을 이용해서 주로 python과 C를 연결했었는데, 
이것은 C++과 다이렉트로 연결해주는 패키지이다. 
이전에도 C++은 python과 바로 연결은 안되고, extern이라든지 c형태로 함수를 다시 재구성해서 노출시키는 방법들을 사용했었는데, 이것은 간단한 작성으로 이런것들을 가능하게 해주는듯하다. 

이전에 Boost.Python이 그런역할을 해주는데, 부스트라는게 사실 좀 헤비한 면이 없지 않은지라 header only에 standard c++만 사용한 이 패키지도 나쁘지는 않은듯하다. 


먼저 pybind설치

>> pip install pybind11 

아래와 같이 c-code를 작성한다. example.cpp

#include <pybind11/pybind11.h>

int add(int i, int j) {
    return i + j;
}

namespace py = pybind11;

PYBIND11_MODULE(example, m) {
    m.doc() = "pybind11 example plugin"; // 모듈 독스트링 설정

    m.def("add", &add, "A function which adds two numbers"); // 함수 바인딩
}

이것을 다음과 같이 컴파일 header-only이기때문에 python3 -m pybind11 --includes 이 명령어를 통해서 관련 헤더가 추가된다.


c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` example.cpp -o example`python3-config --extension-suffix`

아래와 같이 python 에서 불러들이면 끝

import example

result = example.add(1, 2)
print(result)  
# 출력: 3

위와 같이 간단하게 python에서 c-code를 실행시키는 코드를 만들수 있다.


2023년 9월 8일 금요일

NumPy Array 생성 함수

 NumPy에서는 다양한 방법으로 배열을 생성할 수 있는 함수들을 제공합니다. 이러한 함수들에 대해서 정리해보았슨비다.

NumPy Array 생성 함수

함수설명예제결과
np.array주어진 데이터로부터 배열을 생성np.array([1, 2, 3])[1, 2, 3]
np.zeros모든 원소가 0인 배열 생성np.zeros((2, 3))[[0., 0., 0.], [0., 0., 0.]]
np.ones모든 원소가 1인 배열 생성np.ones((3, 2))[[1., 1.], [1., 1.], [1., 1.]]
np.empty초기화되지 않은 배열 생성np.empty((2, 2))랜덤 값
np.arange주어진 범위와 간격의 배열 생성np.arange(0, 10, 2)[0, 2, 4, 6, 8]
np.linspace선형 간격의 배열 생성np.linspace(0, 1, 5)[0., 0.25, 0.5, 0.75, 1.]
np.logspace로그 간격의 배열 생성np.logspace(0, 3, 4)[1., 10., 100., 1000.]
np.eye단위 행렬 생성np.eye(3)[[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]
np.random.rand랜덤한 원소를 가진 배열 생성np.random.rand(2, 2)랜덤 값 (0~1 사이)

예제 코드

import numpy as np

# np.array 예제
a = np.array([1, 2, 3])
print("np.array:", a)

# np.zeros 예제
b = np.zeros((2, 3))
print("np.zeros:", b)

# np.ones 예제
c = np.ones((3, 2))
print("np.ones:", c)

# np.empty 예제
d = np.empty((2, 2))
print("np.empty:", d)

# np.arange 예제
e = np.arange(0, 10, 2)
print("np.arange:", e)

# np.linspace 예제
f = np.linspace(0, 1, 5)
print("np.linspace:", f)

# np.logspace 예제
g = np.logspace(0, 3, 4)
print("np.logspace:", g)

# np.eye 예제
h = np.eye(3)
print("np.eye:", h)

# np.random.rand 예제
i = np.random.rand(2, 2)
print("np.random.rand:", i)

이러한 NumPy 함수들을 사용하여 다양한 형태와 속성을 가진 배열을 쉽게 생성할 수 있습니다. 각 함수가 어떤 상황에 유용한지를 이해하면, 이부분 사용하는데 문제없을 듯 합니다.

2023년 9월 6일 수요일

NumPy Broadcasting


Broadcasting은 NumPy 라이브러리에서 다른 형태(shape)의 배열 간에도 산술 연산이 가능하게 해주는 기능입니다. 일반적으로, NumPy에서 배열 간 연산은 배열의 형태가 동일해야 하는데, Broadcasting은 이러한 제약을 완화해줍니다.

기본 규칙

Broadcasting은 다음과 같은 규칙을 따릅니다:

  1. 두 배열의 차원 수가 다르면, 더 작은 차원을 가진 배열의 형태(shape) 앞에 1을 추가합니다.
  2. 두 배열이 어떤 차원에서도 크기가 동일하거나, 한쪽이 1이라면 호환되는 것으로 간주됩니다.
  3. 어느 한 차원에서도 크기가 일치하지 않고 1도 아니라면 오류가 발생합니다.

이것 말은 어려운데 실제 동작하는것보면 쉽게 이해할 수 있습니다.

예제

예제 1: 벡터와 스칼라 덧셈

import numpy as np

a = np.array([1, 2, 3])
b = 2

result = a + b
# result: array([3, 4, 5])

예제 2: 2차원 배열과 1차원 배열 덧셈

A = np.array([[1, 2], [3, 4], [5, 6]])
B = np.array([1, 2])

result = A + B
# result: array([[2, 4], [4, 6], [6, 8]])

장점과 단점

장점

  • 간결성: 더 적은 메모리와 코드로 같은 연산을 수행할 수 있습니다.
  • 성능: Broadcasting을 이용한 연산은 내부적으로 최적화되어 있어 빠른 연산 속도를 제공합니다.

단점

  • 복잡성: Broadcasting 규칙을 이해하지 못하면 예상치 못한 결과를 얻을 수 있습니다.
  • 디버깅: 문제가 발생했을 때, 디버깅이 상대적으로 어렵습니다.

결론

NumPy의 Broadcasting 기능은 배열 연산을 더 간편하고 빠르게 해주지만, 사용에 앞서 해당 메커니즘을 잘 이해하는 것이 중요합니다. 잘 활용하면 다양한 수학적 문제와 데이터 분석 작업에서 큰 이점을 볼 수 있습니다.