블로그

  • IDirect3DDevice9::CreateTexture

    D3DUSAGE
    http://telnet.or.kr/directx/graphics/reference/d3d/constants/d3dusage.htm
    ////////////////////////////////////////////////////////////////////////////////

    D3DPOOL 열거형
    http://telnet.or.kr/directx/graphics/reference/d3d/enums/d3dpool.htm
    ////////////////////////////////////////////////////////////////////////////////

    http://gpgstudy.com/forum/viewtopic.php?t=8829&highlight=%C6%C4%C6%BC%C5%AC+%C1%A4%B7%C4

    SDK 도움말에 설명이 나와있긴하지만.. 그래도 꽤 많은 분들이 헷갈려하시는거 같습니다.

    D3DPOOL_MANAGED 는 풀이 시스템메모리에 백업되고 필요시에 비디오메모리로 로드됩니다. 한번 로드된 풀은 해제되거나 아니면 메모리의 부족으로 강제로 내려갈때까진 메모리상에서 유효합니다.
    시스템메모리에 백업되어있기때문에 디바이스 리셋시에도 별다른 조치를 할 필요가 없습니다.

    D3DPOOL_DEFAULT 는 풀이 비디오메모리에 바로 생성되고 메모리가 부족하면 풀을 만들때 오류를 뱉어냅니다. 따로 백업되어있지않기때문에 디바이스 리셋시에 더이상 유효하지 않게 됩니다.

    D3DPOOL_MANAGED 는 시스템메모리에 백업되어있기때문에 ‘Read’ 하는것에는 별다른 문제가 없습니다. 다만 ‘Write’ 는 하게될때마다 메모리에서 내렸다가 다시 로드되어야되기때문에 무리가 따릅니다. (레퍼런스상에서도 D3DPOOL_MANAGED 로 생성된 버텍스버퍼나 인덱스버퍼는 런타임상에서 업데이트하는걸 성능상에 문제로 추천하고 있지 않습니다. 같은 이유로 렌더타겟같은것들은 D3DPOOL_MANAGED 로 만들수가 없습니다.)

    D3DPOOL_DEFAULT 는 따로 시스템메모리에 백업이 없기때문에 ‘Read’ 에 무리가 있습니다. 다만 ‘Write’ 하는것에는 D3DPOOL_MANAGED 로 만들어진것보단 적합해서 각종 다이나믹 버텍스버퍼/인덱스버퍼 등에 쓰이게 됩니다.

    다이나믹 버텍스버퍼나 인덱스버퍼를 쓸때 자주 쓰이는 옵션인 D3DLOCK_DISCARD 와D3DLOCK_NOOVERWRITE 는 CPU 와 GPU 의 병목현상을 막기위한 플래그들입니다.
    D3DLOCK_DISCARD 는 현재 드라이버가 잡고있는 풀은 그대로 내버려두고 같은 크기의 새로운 풀을 잡아서 거기에 업데이트를 할수 있게합니다. 그리고 잡고있던 풀이 다 쓰여지고 나면 그 풀을 해제되고 새롭게 만들어졌던 풀이 쓰이게 되는거죠. 드라이버가 다 그릴때까지 멈춰있을수없으니 이런식으로 쓰게 됩니다.
    D3DLOCK_NOOVERWRITE 는 현재드라이버가 잡고있는 풀을 업데이트하지 않겠다고 명시적으로 말하는거가 되겠네요. 렌퍼런스에서는 저 두개의 옵션중에 한가지는 꼭 Lock 할때 써주는것을 추천하고 있습니다. (두개같이 쓰는건 비추하고 있습니다.)

    이런저런 이유로 보통 다이나믹 버텍스버퍼나 인덱스버퍼를 쓸때는 조금 큰 하나의 풀을 잡아놓고 거기에 조금씩 알맞는 플래그로 업데이트해가며 렌더링하는게 여러가지면에서 좋은거 같습니다.

    unsigned int uOffset = 0;
    Loop {
    unsigned int uVertexSize = …;
    if(uOffset+uVertexSize > uVertexBufferSize) {
    uOffset = 0;
    }
    unsigned long dwLockFlag = D3DLOCK_DISCARD;
    if(uOffset > 0) dwLockFlag = D3DLOCK_NOOVERWRITE;
    pVertexBuffer->Lock(uOffset, uVertexSize, …, dwLockFlag);

    pVertexBuffer->Unlock();
    DrawPrimitive(…);
    uOffset += uVertexSize;
    }

    1.
    D3DPOOL_MANAGED 나 D3DPOOL_DEFAULT 나 업데이트를 하지 않는다는 조건에서는 성능은 같습니다. (다만 D3DPOOL_MANAGED 로 생성된 많은양의 풀들이 한꺼번에 비디오메모리로 로드되는 순간에는 버벅임같은것을 느낄수는 있습니다.)
    2.
    D3DPOOL_MANAGED 로 생성된 풀을 런타임상에서 계속 Lock/Unlock 하는건 DrawPrimitiveUP 보다 더 느릴수도 있습니다.
    3.
    모두 D3DPOOL_DEFAULT 로 바꾼다면 비디오메모리가 부족하면 아예 풀생성 자체가 안됩니다. 용도에 따라 꼭 D3DPOOL_MANAGED 가 되어야되는경우도 있습니다. (텍스쳐같은걸 Lock/Unlock 등을 통해서 읽어야되는경우) 레퍼런스상에서는 특별한 경우를 제외하곤 D3DPOOL_MANAGED 를 쓰라고 하고 있습니다.

  • z-Fighting

    https://blog.naver.com/leviskim17/130079644697

    1. 깊이 버퍼의 크기를 16Bit로 되어 있으면 24Bit로 사용한다.

    깊이 버퍼의 대역을 늘려줌으로써, 수용 가능한 좌표계를 늘린다.

     D3DParams.AutoDepthStencilFormat = D3DFMT_D24S8;
     D3DParams.EnableAutoDepthStencil = TRUE;

    2. 좌표계를 작게 사용한다.

    위와 같은 맥락으로, Z버퍼는 한정적인데, 무한하게, 맵을 키울경우 Z- Fighting이 발생하기 때문에,

    애초에 좌표계를 너무 큰 것을 사용하지 않는 것이 좋다.

    쉽게 얘기하면, 맵을 mm로 기준 단위로 나눈다든지.

    너무 큰 맵을 사용한다든지,(물론 기준 단위도 크면 상관없지만,)

    그러면 나중에 Z들끼리 싸우는 수준이 아니라, 정말 Z와 Fighting하여야 한다.

    3.  NearZ – FarZ(Z투영 밀어내기)

    정상적인 방법이라기 보다는,

    사실 Z-Fighting에서 정상적인 방법은 1번,2번까지다. 1번,2번의 한계를 넘으면 발생하는 것이 Z-Fighting이니까..

    d3dx9math.h

    // Build a perspective projection matrix. (left-handed)
    D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovLH ( D3DXMATRIX *pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf );

    Perspective 위 함수 단어에서도 알 수 있듯이, 원근이다. 이 원근값은 NearZ – FarZ를 기초로 해서, 행렬을 만들게 된다.

    이 투영 행렬을 살짝 변경 시켜서,  Z-Fighting을 일으키는 오브젝트를 투영된 화면 속에서 살짝 밀어내는 방법이다.

    D3DXMATRIX mProjMat;             // 현재 투영 행렬 저장
    D3DXMATRIX mZBiasedProjMat; // ZBias 적용된 투영행렬 저장float g_fNearClip =  1.0f;       // 투영 행렬 제작 시 사용될 기본 NearClip값
    float g_fFarClip = 100.0f;       // 투영 행렬 제작 시 사용될 기본 FarVisuality값
    float g_fNearClipBias =  0.0f; //투영을 살짝 변경 시킬 때 사용될 NearClip값
    float g_fFarClipBias =  0.5f;   //투영을 살짝 변경 시킬 때 사용될 FarVisuality값

    // 투영 행렬은 렌더링 함수 외부에서 계산을 수행할 때 가장 혼동이 적다.
    //살짝 변경될 투영을 만든다.
    D3DXMatrixPerspectiveFovLH( &mZBiasedProjMat, D3DX_PI/4,(mProjMat._22/mProjMat._11), 
    g_fNearClip + g_fNearClipBias,
    g_fFarClip + g_fFarClipBias  );

    // 원래 투영 행렬 로드시킴
    m_pd3dDevice ->SetTransform( D3DTS_PROJECTION, & mProjectionMat);

    뒤에 그려질 오브젝트를 그려주자.

    // 살짝 변경된 투영을 셋트시킨다.
    m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mZBiasedProjectionMat);

    앞에 그려질 오브젝트를 그려주자.

    // 원래 투영 로드됨…
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, & mProjectionMat);

    결국 두 오브젝트는 겹쳐 있으면서도 Z버퍼로 다른 값을 가지게 되기 때문에, Z-Fighting 현상이 해결된다.

    이 방식은 모든 그래픽 카드에서 적용되기 때문에, 매우 유용하다.

    4.  NearZ – FarZ(잘못됐지만, 적당히 넘어가기 좋은 방법)

    물론 처음부터 각잡고 개발한 경우에는 이런 경우가 없지만, 항상 예외의 상황은 있는 법.

    예를 들면 어떤 모듈 Dll을 사용하고, 그 Dll에서 Rendering을 하는데,

    어떤 놈이 만들었는지 모르겠지만, Z-Fighting이 신나게 발생한다. 이미 그 개발자는 사라지고 없다.

    내부적으로 Rendering에 어떤 제어를 전혀 할 수 없는 상황이다.(개발자에게는 참 여러가지 상황이 닥치지요.)

    이럴 때, 사용하기 좋은 법이라 할 수 있다.

    Z-Fighting이 줄어 들 때까지, NearZ를 줄여나간다. 물론 너무 많이 줄이면 중간에 구멍이 생기기 때문에,

    한계가 있는 방법이지만,

    24bit일 때 FarZ가 10만 이하 정도라면, 티도 안나게 Z파이팅을 해결 될 수도 있다.

    이렇게까지 해도, 안 잡히면, 그때는 말로 풀자 -.-.

    5. ViewPort

    3번과 같은 맥락이다. 다만 이미 만들어진 ViewPort를 약간 변경 시킬 뿐이다.

    D3DVIEWPORT9 mViewPort;   // 현재 뷰포트 저장
    D3DVIEWPORT9 mNViewPort; // 새로운 뷰포트 저장

    // 뷰포트 변경을 의해 사용될 값
    // 1의 ZBIAS 값을 강제 연산   MinZ – 256/(2^24-1), MaxZ – 256/(2^24-1)
    // 2^24 는 설정한 Z버퍼, 

    //256은  Intel (R) Integrated Graphics 나타낸다. 16의 배수라면 어떤 것이라도 상관없다.
    float g_fViewPortBias = 0.0000152588f;

    //기존 ViewPort저장
    m_pd3dDevice->GetViewport(&mViewport);

    // 기존 ViewPort를 mNewViewport에 복사.
    mNewViewport = mViewport;

    // bias 적용
    mNewViewPort.MinZ -= g_fViewportBias;
    mNewViewPort.MaxZ -= g_fViewportBias;

    // 기존 뷰포트 셋팅
    m_pd3dDevice->SetViewport(&mViewport);

    후면에 그릴 것

    // 새로운 뷰포트 셋팅
    m_pd3dDevice->SetViewport(&mNewViewport);

    앞면에 그릴 것

    // 기본 뷰포트 셋팅
    m_pd3dDevice->SetViewport(&mViewport);

    6. Depth Bias.

    Z-Fighting해결법 중에 가장 형식 있어 보이지만, 그래픽 카드에서 지원을 해줘야 한다. Caps로 먼저 확인하자.

    방식은 D3DRS_SLOPESCALEDEPTHBIAS 및 D3DRS_DEPTHBIAS 렌더 옵션을 가지고, 적당히 offset을 주면,

    Z-Fighting을 그래픽 카드에서 핸들을 알아서 해준다.

    물론 내부적으로 어떻게 움직이는지는 알 수가 없고, 추측만 난무할 뿐이다.

    BOOL    m_bDepthBiasCap;        // 장치가 DepthBias 기능을 가지고 있으면 TRUE

    // Depth Bias 가 사용하는 전역 변수
    float g_fSlopeScaleDepthBias  = 1.0f;
    float g_fDepthBias                   = -0.0005f;
    float g_fDefaultDepthBias        =  0.0f;

    // 새로운 depth bias 기능을 지원하는지 검사
    if ((pCaps->RasterCaps & D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS) &&
         (pCaps->RasterCaps & D3DPRASTERCAPS_DEPTHBIAS))
    {
        m_bDepthBiasCap = true;        // DepthBias 기능이 있다면 TRUE
    }

    // 빌보드 렌더링됨 …

    // DepthBias 적용됨
    if ( m_bDepthBiasCap ) // DepthBias가 지원된다면 TRUE

        // z-fighting 을 줄이기 위해서 평면상의 프리미티브에

        // bias 가 적용될 크기를 결정하기 위해서 사용됨
        // bias = (max * D3DRS_SLOPESCALEDEPTHBIAS) + D3DRS_DEPTHBIAS,
        // 여기에서 max 는 렌더링되는 삼각형의 최대 깊이 기울기(slope) 이다.

        // (역주 : F2DW 는 float 을 DWORD 처럼 읽기 위한 매크로)
        m_pd3dDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS,

            F2DW(g_fSlopeScaleDepthBias));
        m_pd3dDevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW(g_fDepthBias));
    }

    // 포스터가 렌더링된다…

    if ( m_bDepthBiasCap ) // DepthBias 가 지원된다면 TRUE

        // DepthBias 적용한다.

        // 그것을 다시 0(기본값)으로 설정한다.
        m_pd3dDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS,

            F2DW(g_fDefaultDepthBias));
        m_pd3dDevice->SetRenderState(D3DRS_DEPTHBIAS,

            F2DW(g_fDefaultDepthBias));
    }

  • Introduction of Adaptive Signal Process

    [Introduction of Adaptive Signal Process]

    이번 포스팅에서는 Adaptive Signal Processing 이 어디에 어떻게 쓰이는지, Filtering 이 무었인지 등의 기본이 되는 이론들을 소개할까 합니다.

    전체적인 틀을 크게 한번 보고 나서 세부적인 부분을 다루면 그만큼 이해하기 쉬울것 같아서요 ㅋㅋㅋ

    1. 필터링이란 무엇인가? (What the filtering is for?)

    : 여러가지 다양한 정의가 있겠지만, 저는 이렇게 정의 내린답니다. ” 신호 중에서 원하는 정보를 뽑아 내는것 ” R.P 에서 원하는 정보라 함은 “원하는 통계적 특성” 이 되겠지요? statistical moment 용 ㅋㅋㅋ

    filter 로 할 수 있는 작업을 크게 3가지로 나누어 보겠습니다.

    (1) filtering
    (2) smoothing : 측정된 데이터를 이용하여 현재의 출력값을 결정하는 방법입니다. 다양한 스무딩 방법이 있지만 그중에서도 Adjacent Averaging method 와 Savitzky-Golay method 이 대표적이죠? 저는 이중에서도 후자인 Savitzky-Golay Smoothing filter 를 주로 쓴답니다 ㅋㅋ

    요론식으로 스무딩 된답니다 ㅋㅋ 상기 그림은 제가 뽑아낸 호흡 신호를 스무딩한 그림입니다. ㅋ 스무딩 필터 이야기 하는 곳이 아니므로 관심 있으신분들은 개인적으로, 댓글로 해결하도록 해요 ㅋ

    (3) prediction : forward prediction 과 backward prediction 이 두가지로 나눌수 있습니다. 너무 직관적이죠 이름이? ㅋ 과거의 정보로 미래에 일어날 일들을 예측하는 것을 forward prediction 이라고 합니다. 그 반대가 backward prediction 입니다.

    (4) Examples of the linear filtering

    i) Wiener filter : linear optimum system 설계시 주로 이용됩니다. 영상처리나 뇌파 분야, 즉 rp 를 다루는 분야에서는 이 필터에 익숙하실 것입니다. 신호의 통계적인 특성들을 알고 있을 때 사용할 수 있습니다. mean square 기반으로 target 신호와 내가 만든 모델 신호간의 error 를 최소화하려는 시도라 볼 수 있습니다. 다만 가장 큰 단점으로, nonstationary signal 에 적용하기에는 부적적합니다.

    ii) Kalman filter : 가속도 센서와 자이로센서의 출력을 융합하는데 주로 쓰이지요? ㅋ 쿼드콥터 등이 보편화된 이 시기에 대학 학부생들의 입에서도 이 단어가 심심치 않게 들립니다. 굉장히 복잡한 개념이지만, signal 의 trend 를 잘 따라갈 수 있게 해주는 filter 입니다. 추정값을 쓸 수 있는 모델링 된 식이나, reference signal 이 꼭 있어야 합니다. 이 부분은 훗날 기회가 된다면 다시한번 포스팅 하도록 하겠습니다. 이 Adaptive filtering 포스팅의 최 후반부가 되어야 겠군요 ㅋㅋㅋ

    2. Adaptive Filter 란 무엇인가??

    많은 사람들이 이렇게 물어보면 막연하게 대답합니다. 어떻게 동작하는지는 알겠는데 도대체 뭐를 구해내겠다는건지를 모른채 그 용도에만 초점을 맞추고 있는 것이지요. 여기서 한번 알아보겠습니다. Wiener filter 를 이야기할때 최적 필터 (optimum filter) 에 대해서 잠시 이야기 하였지요? 통계적 특성이 변화하지 않는 신호일때 Wiener filter 를 이용하여 최적 필터 계수를 구해낼 수 있습니다. 헌데…. 시간이 지남에 따라 통계적 특성이 달라지는 신호라면?? 혹은 실시간으로 신호가 들어오기 때문에 신호의 통계적 특징을 모르는 상태라면?? 난감하죠??
    그래서 Adaptive filter 가 등장하게 됩니다. 1975 년에 Widraw 인가? 정확학 스팰을 모르겠네요 ㅋㅋ 여튼 이사람과 아이들에 의해서 LMS 알고리즘 기반의 Adaptive Filter 의 개념과 Application 이 등장하지요

    즉, Adaptive Filter 는 시간이 지남에 따라 통계적인 특성이 달라지는 non-stationary 한 시그널을 포함해서 이 신호에 대해 샘플이 들어오는 매 시간마다 Optimum Wiener Filter 의 계수를 추정해 가는 알고리즘들을 통틀어서 Adaptive Filter 라고 부릅니다. 이렇게 추정해가는 방법이 LMS 알고리즘 기반으로 찾느냐 RLS 기반의 방법으로 찾느냐 등에 따라 적응필터의 이름이 바뀐답니다. ㅋ

    이 때 사용되는 필터의 형태는 FIR, IIR 모두 상관 없지만, 필터의 시스템이 발산하지 않게 하도록 하기 위해서 FIR 필터를 대부분 사용합니다. 왜 FIR 필터의 시스템이 안정적인지에 대해서는 모두 아시리라고 굳게 믿습니다.

    뒷부분에서 자세하게 다루겠지만 최적 필터 계수란 것은 아래의 그림과 같습니다. 벡터의 내적이나 함수의 내적을 생각해 보시면 되겠네요. 공업수학에서 내적 이야기할때 기준 벡터로의 투영 (Contour) 이야기 많이 했었지요? 이 벡터가 다른 한 벡터의 방향으로 얼마의 크기성분을 가지고 있는가 ? 를 계산하는것이 내적 아닙니까 ㅋㅋ 신호(함수) 의 내적도 같습니다.

    이 그림을 보십시요. 측정한 신호 u(n) 의 크기를 조절해 (w) 소망 신호인 d(n) 과의 거리가 가장 가까워지도록 만들면? 그것이 최적의 필터가 되겠지요. Error 가 가장 적어지는 것이니까요. Weighting Factor 를 곱하기만 해서 신호 벡터의 방향을 바꿀 수는 없습니다. 결국 크기를 얼마나 조절하느냐 라는 개념이라고 단순화 시켜 생각할 수 있는데 그 때 그 차이 크기가 가장 작아지도록 하는 계수들 w matrix 를 갖는 필터를 optimum filter 라고 부를 수 있는 것입니다.

    Adaptive Filter 를 구현함에 있어서 고려해야할 Factor 들이 있습니다. 지금은 어떤것들이 있는지 일단 알아보기만 하겠습니다.

    (1) Convergence rate (수렴속도) : 얼마나 빨리 Optimum Filter 상태로 수렴해 가는가?
    (2) Misadjustment (적응정도) : 수렴한 후에는 얼마나 계수의 변화폭이 큰가? (수렴후에는 변화폭이 작을수록 좋다)
    – (1), (2) 은 Trade-Off 관계에 있습니다 ㅋㅋㅋ

    (3) Tracking : 얼마나 원하는 신호를 잘 추적해 가는가?
    (4) Robustness : 필터의 구조가 탄탄한가? 모든 신호에 일관성 있게 적용되어 출력되는가?
    (5) Computational requirement : 알고리즘의 계산량은 얼마나 되는가?
    (6) Structure : 필터의 구조가 얼마나 복잡한가?
    -(5), (6) 은 실시간으로 mcu 나 DSP 칩에서 구현을 하지 위해 연산속도와 battery 소모 등을 고려하기 위해서 고려하는 것입니다.

    3. 필터의 구조 (Filter Structures)

    (1) FIR structure

    i) Transversl (Taped-delayed line) : 우리가 흔히 아는 FIR filter 구조입니다. 최대 FIR filter 의 Order 만큼의 delay 가 발생되며, 각각의 샘플에 원하는 w 가 곱해진 후 모두 더해지는 구조로 되어있지요? 출력이 다시 입력으로 feedback 되거나 입력이 출력쪽으로 feedforward 되지 않는다는 점도 유의해서 볼 필요가 있군요

    ii) Lattice, escalator (Gram-Schmidt)

    흐음.. 이게 저도 잘 모르는 부분인데요 ㅋㅋㅋ Lattice(격자) 구조와 위에서 설명한 TDL 구조 두개를 합쳐서 만듭니다. 왜 그러냐면 통계적으로 상관이 없는 신호 (uncorrelated) 된 신호는 변환 속도가 빠르답니다. 그래서 Lattice 구조를 통해 신호의 통계적 특성을 없앤 후에 TDL 구조로 필터링을 하는 구조로 되어있어요

    요론 구조인데요 ㅋㅋ 아직 저도 완벽하게 모르고 사용도 안해본지라 ㅋㅋ 훗날 쓰게 되면 한번 포스팅 하도록 하겠습니다. 고수분들이 있으시면 댓글로 설명좀 해주십시요 ㅋㅋ

    iii) Systolic array

    Parallel computing 이 가능한 구조라는거 같은데 ㅋㅋ ii) 도 완벽하게 정복 못한 제가 iii) 에 대해 씨부리면 거의 대부분이 잘못된 정보일듯 ㅋㅋㅋ 여기서 함구할테니 훗날을 기약하시던지 아니면 지나가던 강호 무림의 고수분이 댓글로 알려주시기를 바래야겠습니다 ㅋㅋ

    (2) IIR structure : 특별히 언급할 것은 없습니다. 출력의 Feedback 에 의해서 Stability 의 문제가 발생할 수 있습니다. 그래서 ㅋㅋㅋ FIR 형태로 Adaptive Filter 를 주로 만든다고 위에서 말씀드렸죠? ㅋ

    4. Linear Adaptive Filter algorithms (선형 적응 필터의 알고리즘 종류)

    (1) Stochastic gradient approach

    – Cost function 의 MSE (Mean Square Error) 의 크기를 최소화 하겠다는 발상입니다. 이를 통해 최적 Wiener filter 의 계수를 추정해 가는 과정입니다. 대표적으로 LMS (Least mean square) 알고리즘이 있습니다

    ex) TDL filter with the LMS algorithm

    장점 : 매우 간단하고 효율적입니다. C 로 코드를 짤 경우 3줄 밖에 되지 않습니다.
    단점 : 수렴 속도가 다른 알고리즘에 비해 상대적으로 느립니다.

    (2) Least-squares estimation

    – Weighting factor 가 곱해진 에러 제곱의 합을 최소화 하겠다는 발상입니다. 대표적으로 RLS 알고리즘이 있습니다.

    es) TDL filter with the LS algorithm

    장점 : 수렴 속도가 빠릅니다.
    단점 : 계산량이 다른 알고리즘에 비해 상대적으로 많습니다. 따라서 알고리즘 구현도 복잡합니다.
    matrix inversion 에 의해 대수학적으로 안정적이지 않을 수 있다는 잠재적인 문제점을 앉고있습니다.

    RLS, fast RLS, QR-decomposition 등의 알고리즘이 LS 기반의 알고리즘입니다.

    5. Adaptive filter applications (적응 필터로 할 수 있는 것들)

    – 이거이거 굉장히 중요합니다. 어디다 어떻게 쓸 수 있는지 알아야 뭘 써먹든 말든 하지요. 외울 필요도 없습니다. 블럭도를 보고 “입력이 이렇고 출력이 이러니까 이것은 이것이다.” 라고 이해 할수 있어야 합니다. 흔히들 생각하는 필터링 이외에서 모델링, 예측, 노이즈 캔슬레이션 등에 다양하게 이용할 수 있습니다. 그럼 하나씩 알아 볼깝숑?

    (1) System identification

    : 이름 무시무시 합니다. 시스템을 정의 내리겠습니다. 모르는 어떤 시스템으로 들어가는 입력 신호를 ADF 의 입력으로 사용하고, 시스템의 출력과 ADF 의 출력의 차이 (Error) 를 최소화 함으로써 모르는 시스템을 배껴버리겠다는 소리죠. 모르는 시스템을 표현할 수 잇는 filter 의 계수를 알아버렸기때문에 우리는 모르는 시스템을 모델링 해버렸다고 생각할 수 있는것입니다. 그럼 이 글을 그림으로 블럭화 시키면 어떻게 되는지 한번 알아볼깝숑?

    이렇게 표현이 가능합니다. 자세한 구현 알고리즘은 훗날 다루도록 하고 아래에는 예제 그림을 보여드리도록 하겠습니다.

    사진이 왜 이따위로 나오지? ㅋㅋ 여튼 ㅋㅋㅋ
    White noise 를 이용해서 어떤 필터를 건 출력을 추정 해 본 것입니다. 아래그림의 빨간색을 보시면 처음에는 헤롱헤롱해서 이상한 값을 뿌리지만 뒤로갈수록 정확하게 추정하는 것을 알 수 있습니다. 이 때 추정된 계수 w 는 처음 입력신호에 취했던 fir 필터의 계수와 일치합니다. 즉, 우리는 모르는 시스템(여기서는 filter) 을 추정 했다고 볼 수 있는 것이지요.

    (2) Inverse modeling

    : 이것도 외우지 마시고, 이렇게 생각하십시요. ADF 의 입력으로 어떤 모르는 시스템의 출력이 사용되고, ADF 의 출력과 어떤 시스템에 들어간 입력신로를 딜레이 시킨 신호와의 에러를 최소화 시켜 어떤 모르는 시스템의 입력값을 유추해 내겠다. 이때 delay 된 input 을 사용하는 것은 system 의 causality 를 위함입니다. 즉, Inverse modeling 이 되는 것이지요. 위와 거의 비슷한 과정이기 때문에 따로 예제는 보이지 않겠습니다. 아래 보이는것이 이 개념의 블럭도 입니다.

    (3) Prediction

    ADF 의 입력으로 delay된 input signal 을 사용하고 ADF 의 출력과 딜레이 되지않은 input 의 Error 를 최소화 시킴으로써 과거의 입력으로 미래의 출력을 예측할수 있게 할 수 있습니다.

    짱 신기하지 않습니까? ㅋㅋ 저는 짱 신기했는데 ㅋㅋ

    흠. 이것도 화질이 그리 좋지 않네요 ㅋㅋ 하지만 보십시용 빨간색이 ADF 출력이고 파란색이 입력 시그널 입니다.
    초기에 빨간색 라인이 보이는 이유는 딜레이 되어있기 때문이겠지요? ㅋ 하지만 시간이 지나 수렵해 가면서 어떻게 되었습니까? ㅋ 빨간색이 거의 보이지 않죠? ㅋ 딜레이된 입력을 사용해서 미래의 출력값을 예측해 입력파형과 똑같은 출력을 ADF 가 내보내고 있기 때문이랍니다 ㅋㅋ 신기하지 않습네까? ㅋㅋㅋ
    이거 잘하면 어디다 이용할수 있나염? ㅋㅋ 주식!!!! ㅋㅋㅋ 세상만사 ADF 와 같다면 정말 대박이겠다 ㅋㅋㅋ

    (4) Interference cancelling

    이게 우리가 가장 DSP 에서 흔히 쓰이는 개념이지요 ㅋ Noise Cancelling 도 이 개념입니다. 내가 측정한 신호를 ADF 의 입력으로 사용하고 ADF 의 출력과 내가 바라는 신호와의 차이를 최소화 함으로써 원하지 않는 노이즈성분만을 따로 뽑아내는것입니다. 60Hz 전원 노이즈 제거 등에 주로 쓰이지요? ㅋㅋ 더 나아가면 태아 심전도를 디텍팅 하는쪽에서도 쓰입니다.

    아래는 예제 입니다.

    25Hz 와 60Hz 를 섞어서 60Hz 만 제거를 해보았습니다. 검증을 FFT 를 이용해 주파수 분석을 함으로써 60Hz 가 빠진것을 보여드리도록 하곘습니다. ㅋㅋ