파이썬의 numpy, scipy, 심지어 sympy 까지 있는데 MATLAB의 control system toolbox 같은 것은 없나.. 하고 생각했었는데 있었다. 사용자 매뉴얼을 아래에 링크하였다.

python control system library User's manual


이 모듈은 winPython 에서 기본적으로 설치되어 있지 않다. 하지만 윈파이썬의 콘솔창(Tools > Open command prompt) 에서 다음과 같이 명령을 내리면 자동으로 인스톨된다.

------------------------------------------------------------------------
> pip install control
------------------------------------------------------------------------

이 라이브러리는 기본적인 선형제어 시스템에 관련된 함수들과 클래스가 정의되어 있고 MATLAB control toolbox 와 이름체계가 비슷한 것 같다.

이제 simulink 같은 툴만 나오면 되는 건가.. 갈수록 파이썬에 놀라는 중이다.

[#00084]

Posted by 살레시오
,

  넘파이의 ndarray 객체는 리스트와 달리 브로드캐스트(broadcast)라 불리는 특성이 있는데 이는 리스트(list)객체와 확연히 구별이 되는 기능이다. 예를 들어서 다음과 같이 숫자로만 이루어진 중첩 리스트 la 를 고려해 보자.


-----------------------------------------------------------------------

>>> la = [ [1,2], [3,4] ]

-----------------------------------------------------------------------


이 리스트는 요소가 모두 숫자이지만 la+2, la/4 와 같은 연산은 지원하지 않는다. 모든 요소에 2를 더하려면 for 반복문을 사용해야만 한다. 그리고 la*2는 파이썬 문법상 전혀 다른 동작을 수행한다. 즉, 리스트 사이의 사칙연산은 수학 연산과는 전혀 관계가 없는 것이다.


  이에 반해서 ndarray는 요소간 연산이 기본적으로 가능하며 같은 크기의 객체간 산술연산은 요소끼리 행해져서 그 결과가 산출된다. 예를 들어서 다음과 같은 두 개의 ndarray 를 고려하자.


-----------------------------------------------------------------------

>>> a = np.array( la )

>>> b = np.array([[1j,2j],[3j,4j]])

-----------------------------------------------------------------------


이렇게 생성된 a와 b에 대해서는 a+1, a*3, a-b 와 같은 사칙 연산이 정의되며 각각의 요소에 대해서 연산이 수행된다. 배열간 곱셈의 경우는 행렬곱셈과는 상관이 없는 연산이므로 이것과 헷갈리면 안된다. 여기서의 곱셈은 요소간 곱셈이다. 이러한 ndarray 의 기능을 broadcast라고 한다.


  그럼 크기가 다른 객체간 연산은 어떨까? 먼저 한 쪽이 배열이고 다른 쪽이 스칼라라면 그 스칼라는 다른 배열의 크기로 확장된 후 각각의 요소에 더해진다.


-----------------------------------------------------------------------

>>> np.arange(5) + 2 # [0, 1, 2, 3, 4] + [2, 2, 2, 2, 2] 와 같다

array([2, 3, 4, 5, 6])

-----------------------------------------------------------------------


이 예를 보면 1x5 크기의 배열과 2라는 스칼라의 합이다. 2라는 스칼라는 모든 요소가 2인 1x5의 배열로 확장된 후 각 요소간 더해진다. 행렬의 경우도 마찬가지이다.


-----------------------------------------------------------------------

>>> a=np.arange(1,10).reshape(3,3) # [0,1,2, ... ,9] 배열은 3x3로 재배열한다.

>>> a**2

array([[ 1, 4, 9],

[16, 25, 36],

[49, 64, 81]])

-----------------------------------------------------------------------


크기가 다른 행렬 간에는 산술연산이 일반적으로 불가하다. 즉, 다음과 같은 행렬 a, b 간의 산술연산은 불가능하다.


-----------------------------------------------------------------------

>>> a=np.arange(1,10).reshape(3,3)

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

>>> a+b # 에러 발생

-----------------------------------------------------------------------


하지만 가능한 경우가 있으니 다음의 세 가지 경우이다.


  • mxn 행렬과 mx1 벡터 간의 연산
  • m x n 행렬과 1xn 벡터 간의 연산
  • 또한 mx1 벡터와 1xn 벡터간의 연산.


이 세가지 경우는 한 쪽의 크기가 다른 쪽의 크기로 확장된 후 요소간 연산을 수행하게 된다. (다음 그림 참조)


[#00083]

Posted by 살레시오
,

  numpy를 이용해 생성된 ndarray객체는 다양한 field와 method를 갖고 있다. ndarray객체의 field/method는 dot(.)연산자를 이용하여 접근할 수 있다. (마치 C언어의 구조체나 공용체의 필드에 접근하는 방식과 같다.)

배열의 모양에 관련된 attribute 들

먼저, ​전치행렬을 구해주는 T attribute가 있다.

​-------------------------------------------------------------------------
>>> x = np.array([[1.,2.],[3.,4.]])

>>> x
array([[ 1., 2.],
​[ 3., 4.]])

>>> x.T
array([[ 1., 3.],
[ 2., 4.]])

>>> x = np.array([1.,2.,3.,4.])
>>> x
array([ 1., 2., 3., 4.])

>>> x.T # 1차원 배열에서 T attribute 는 동작하지 않는다.
array([ 1., 2., 3., 4.])
​-------------------------------------------------------------------------​​

위에서도 언급되었지만 1차 배열에서는 이것이 동작되지 않는다는 것을 주의해야 한다. 만약 배열 A의 복소전치행렬을 구하고 싶다면 A.conj().T (혹은 A.T.conj() ) 라고 하면 된다. 그리고 M이 행렬객체라면 단순히 M.H 라고 하면된다.

배열의 크기에 관련된 attribute 들

  배열의 크기에 관련된 attribute로 ndim, shape, 그리고 size가 있다. 이 중 shape는 읽기뿐만 아니라 쓰기도 가능하다.

  ndim 은 배열이 몇 차 배열인지를 알려준다.


​-------------------------------------------------------------------------
>>> x = np.array([1, 2, 3])
>>> x.ndim
1
>>> y = np.zeros((2, 3, 4))
>>> y.ndim
3
​-------------------------------------------------------------------------

​shape는 배열의 각 차수별 크기를 튜플로 반환하거나 지정해 줄 수 있다. 단, shape를 변경할 때는 변경 전과 전체 요소의 숫자가 같아야 한다.

​-------------------------------------------------------------------------
>>> x = np.array([1, 2, 3, 4])
>>> x.shape
(4,)
>>> y = np.zeros((2, 3, 4))
>>> y.shape
(2, 3, 4)
>>> y.shape = (3, 8)
>>> y
array([[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.]])
>>> y.shape = (3, 6)
Traceback (most recent call last): File "<stdin>", line 1, in <module>
ValueError: total size of new array must be unchanged
​-------------------------------------------------------------------------

size는 ​​전체 요소들의 개수를 반환하며 np.prod(obj.shape)와 같은 결과를 생성한다.

​-------------------------------------------------------------------------
>>> x = np.zeros((3, 5, 2), dtype=np.complex128)
>>> x.size
30
>>> np.prod(x.shape)
30
​​-------------------------------------------------------------------------

기타

​나머지 attribute 들은 다음 표에 정리하였다.

TSame as self.transpose(), except that self is returned if self.ndim < 2.
data

배열의 시작을 가리키는 파이썬 버퍼 객체 

dtype

배열 요소의 데이터형 

flags

배열의 메모리 구조에 대한 정보 

flat

배열의 1차원 반복자 

imag배열의 허수부
real배열의 실수부
size배열의 요소 전체의 개수
itemsize배열 요소의 바이트 크기
nbytes배열의 전체 요소가 차지하는 바이트 크기
ndim배열의 차수
shape배열의 차수별 크기.
stridesTuple of bytes to step in each dimension when traversing an array.
ctypesAn object to simplify the interaction of the array with the ctypes module.
baseBase object if memory is from some other object.

[#00082]

Posted by 살레시오
,