임베디드 프로그래밍을 하다 보면 레지스터 등의 설정을 2의 보수로 해야 하는 경우가 많이 있습니다. int 값을 2의 보수 헥사값으로 표현하거나 또는 2의 보수 헥사 값으로부터 int 값을 구하는 경우 저는 주로 Python bitstring 모듈을 사용하곤 합니다.

대부분의 파이썬 모듈이 그렇듯이 bitstring 모듈 역시도 pip를 통해 아래와 같이 설치할 수 있습니다.

pip install bitstring

사용은 아래와 같이 bitstring 모듈을 import 를 하고~

from bitstring import Bits

헥사값을 넣어 줍니다.

num = Bits(hex="FFD856")

int 값을 구하기 위해서는 int 멤버 변수 값을 확인하면 되고 아래 예를 보면 -10154 임을 알 수 있습니다.

hex 값을 구하기 위해서는 hex 멤버 변수 값을 확인하면 ffd856 임을 알 수 있고~ bin 값을 구하기 위해서는 bin 멤버 변수 값을 확인하면 "111111111101100001010110' 임을 알 수 있습니다.



 MATLAB math toolbox 를 이용한 미분은 diff() 함수를 통해 구할 수 있습니다.

 

다음 식에 대하여 diff() 함수를 이용하여 미분을 수행해 보죠.

 

 

 

syms x

 

f = x^4+3*x^2+x+2

 

f =

x^4 + 3*x^2 + x + 2

 

diff(f, x) % f 값을 x 대하여 미분

 

ans =

4*x^3 + 6*x + 1

 

diff(f, x, 2) % f 값을 x 대하여 2 미분

 

ans =

12*x^2 + 6

 

 

 

 

Symbolic 식에 대한 적분은 int() 함수를 통해 이루어 집니다.

 

정적분 뿐만이 아니라 부정 적분도 수행 합니다.

 

 

 

 

int(f,x) % 부정 적분

 

ans =

x^5/5 + x^3 + x^2/2 + 2*x

 

int(f, x, 1, 5) % 1~5 구간에 대한 적분

 

ans =

3844/5

 

 

 

 

 

임의의 구간에 대한 적분도 가능 합니다.

 

위 식을 구간 임의의 구간 a ~ b 에 대해 적분을 수행해 보죠

 

일단 a, b 값을 symbolic 변수로 설정 해 줍니다.

 

 

 

syms a b

 

int(f, x, a, b)

 

ans =

b*(b*(b*(b^2/5 + 1) + 1/2) + 2) - a*(a*(a*(a^2/5 + 1) + 1/2) + 2)

 

 

 

위 식과 같이 임의의 구간에 대해서도 적분가능 한 것을 확인 할 수 있습니다.


MATLAB 을 이용하여 적분을 수행해 보자. MATLAB 을 이용하여 적분을 하는 방법은 크게 두 가지 정도로 구분 할 수 있을 것 같다. 

첫 번째로는 수치적인 적분 방법이고 두 번째는 Symbolic math toolbox 를 이용한 수학적인 접근 방법이다.

수치적인 접근 방법이라 하면 사다리꼴 방법 과 같이 함수를 매우 작은 조각으로 나눠서 부분부분의 면적의 합을 구하는 방법이 될 것이다. 물론 이런 적분을 구하는 알고리즘을 짜서 적분을 할 수도 있겠지만 고맙게도 matlab 은 이런 함수를 제공 해 준다.

quad() 함수를 이용하면 수치 적분이 가능하다. 본 함수는 수치 적분이므로 부정적분을 해 주지는 못한다. 따라서 다음 수식과 같이 구간이 정해진 식에 대해서만 적분 할 수 있다.

 

 

위 수식에 대한 적분은 다음과 같다.

 

F = @(x) x.^2+2.*x+1

F =

@(x)x.^2+2.*x+1

 

quad(F,0,3)

ans =

21

간단하게 해가 나오는 것을 확인 할 수 있다.

하지만 이런 수치적분은 위에서 밝힌 대로 부정적분이 불가능 하다. 부정적분을 할 때는 symbolic math toolbox 를 이용해야 한다. Symbolic math toolbox 는 Mathematica 나 Maple 과 같이 기호로서 계산을 해주는 툴로서 복잡한 수학 계산시 굉장히 편리하게 이용할 수 있다.

 

다음과 같은 수식에 대해 간단하게 부정적분 그리고 임의의 구간에 대한 적분을 수행 해보자.

 

 

부정적분은 굉장히 간단하다.

symbol 로 사용한 변수인 x 를 symbolic 으로 설정해준다.

 

syms x

int(x^2+2*x+1)

그리고 int() 함수 내에 적분할 수식을 써 준다. int() 함수는 integral 의 약자이다. 위 코드의 실행 결과는 다음과 같은 부정적분 결과가 나온다.

 

ans =

(x*(x^2 + 3*x + 3))/3

 

그럼 임의의 구간 a~b 구간에 대해서도 적분을 해 보자. a, b 도 symbolic 으로 설정을 해 준 후에 int() 함수에서 적분 구간을 a, b 라고 명시 해 준다.

 

syms x a b

int(x^2+2*x+1,a,b)

ans =

b*(b*(b/3 + 1) + 1) - a*(a*(a/3 + 1) + 1)

 

다음과 같이 간단하게 a, b 라는 적분구간에 대해 적분이 실행 되는 것을 확인 할 수 있다.


  1. 조민형 2013.08.09 16:46

    적분 질문 있습니다 ㅠㅠ
    바쁘실텐데 답변 주실 수 있으시려나요..

    매트랩 초보라 왜 이런지 모르겠습니다.

    식이 좀 복잡한데,,

    >> int((64*(cos((B*q*cos(phi))/2)^2 - 1)*(cos((A*q*sin(phi))/2)^2 - 1)*(sin(C*q)/(2*C*q) - 1/2))/(A^2*B^2*C^2*q^6*cos(phi)^2*(cos(phi)^2 - 1)),phi,0,pi/2)
    Warning: Explicit integral could not be found.

    ans =

    int(((cos((A*q*sin(phi))/2)^2 - 1)*(64*cos((B*q*cos(phi))/2)^2 - 64)*(sin(C*q)/(2*C*q) - 1/2))/(A^2*B^2*C^2*q^6*cos(phi)^2*(cos(phi)^2 - 1)), phi = 0..pi/2)
    와 같이 적분을 찾을 수 없다고 나옵니다.

    이런 경우 부정적분 값을 도출할 수 있는 스킬이나 노하우 같은게 있나요??

    답변 미리 감사드립니다 !!

    • 남성 2013.08.09 19:02 신고

      저도 몇가지 방법으로 시도는 해봤는데 마찮가지로 Warning: Explicit integral could not be found. 라는 메시지가 뜨네요. 도움 못되 죄송합니다. ^^;

  2. 서형관 2016.12.02 09:22

    임의의 구간 적분에 대해서 질문이 있습니다.
    매트랩을 인터넷에 올라온 글을 보면서 독학하는중 입니다.
    구간a b c는 a=1000 b=8000 c=9000으로 정의하였고 그 나눈 부분을 적분하는 프로그램을 짜고 있는데

    syms n1 0 a
    n1=int((i*n)/(2*(pi)*a^2),n,0,a);
    syms n2 a b
    n2=int(i/(2*(pi)*n),a,b);
    syms n3 b c
    n3=int((i*(c^2-n^2))/((2*(pi)*n)*(c^2-b^2)),b,c);


    이렇게 만들어 봤는데 쉽지 않네요 ㅠㅠ
    어떤부분이 문제인지 알 수 있으신가요??

    • 남성 2016.12.02 21:03 신고

      다음과 같이 해 보세요.

      a=1000;
      b=8000;
      c=9000;

      syms n
      n1=int((1i*n)/(2*(pi)*a^2),n,0,a)
      double(n1)

      n2=int(1i/(2*(pi)*n),a,b)
      double(n2)

      n3=int((1i*(c^2-n^2))/((2*(pi)*n)*(c^2-b^2)),b,c)
      double(n3)


  3. 크레스포 2017.04.15 18:22

    Syms로 적분한 함수의 그래프를 출력하는 방법은 없나요?

C++ 프로그래밍을 하다 보면 변수의 type 에 따라 함수를 여러 개 작성해야 되는 경우가 많이 있다.

다음과 같이 x3 을 계산을 하는 myfunc() 함수를 가정 해 보자.

위 식에서 x 라는 변수가 int, double 인 경우에 대해 함수를 작성 하면 아래와 같이 될 것이다.

 

  • x 가 integer 인 경우

int myfunc(int x)

{

int t0;

t0 = x*x*x;

return t0;

}

 

  • x 가 double 인 경우

double myfunc(double x)

{

double t0;

t0 = x*x*x;

return t0;

}

 

함수는 오버로딩이 되므로 위와 같이 두 개의 함수를 지정해 놓으면 x 가 int 인 경우나 double 인 경우는 함수가 정상적으로 call 이 되고 동작을 하게 될 것이다.

그런데 저런 똑 같은 함수를 float 와 같은 다른 형태의 변수에 대해서도 써야 할 때가 있다.

이런 경우는 물론 그냥 float 형태로 또 써주면 되긴 할 것이다.

하지만 이러한 코딩 방식은 너무나 비생산 적이다.

이런 경우 template 을 알고 있으면 굉장히 편리 하다.

 

다음과 같이 template 의 형태로 함수를 작성해 보자.

template<typename T>

T myfunc(T x)

{

T t0;

t0 = x*x*x;

return t0;

}

 

위 코드에서 double , int 등으로 작성되었던 부분을 T 라는 타입으로 설정 해주고, 그 위에 T 라는 type 을 갖는 template 이다 라고 선언해 준 것 뿐이다.

이렇게 헤더 파일에 작성을 하면

그 myfunc() 라는 함수는 x 의 타입에 상관없이 이용할 수 있는 함수가 되는 것이다.

template 을 이용하면서 주의 할 점은 꼭 헤더 파일에 놓여야 한다는 것이다.

template 으로 작성된 함수는 컴파일시에 코드가 만들어 진다. 따라서 컴파일 속도가 약간 느려질 수는 있지만 그 영향은 거의 미미하다.

 

template 을 사용하여 지루하기만 했던 C++ 코딩에 날개를 달아보자.

 


+ Recent posts