Peak Detection 알고리즘 - C#

Mathematics Algorithm|2023. 11. 20. 14:01
반응형

아래 이미지와 같은 그래프가 있을때 최고 peak 값 1개를 찾는 것은 쉽다. 

그런데 아래 그림에서 각각의 peak 점을 모두 찾아야 할 경우가 있다. 이처럼 peak 가 여럿인 그래프에서 모든 peak 점을 찾는 알고리즘을 만들어 보았다. 

private List<int> PeakDetect(in double[] data, int count, double threshold)
{
    List<int> peakPos = new List<int>();
    List<int> peaks = new List<int>();
    double[] imsi = new double[count + 1];
    bool peak;

    for(int index = 0 ; index < data.Length - count ; index++)
    {
        Array.Copy(data, index, imsi, 0, count + 1);  // 영역 데이타의 상승 경향을 보기위한 값들을 복사한다. (선택한 카운트 + 1)
        var beforeValue = imsi[0];
        peak = true;

        for(int i = 1 ; i < count ; i++)
        {
            if(beforeValue <= imsi[i]) beforeValue = imsi[i];  // 데이타가 계속 상승하는 곡선인지 확인 
            else
            {
                peak = false;  // 중간에 값이 하강하면 Peak 가 아니다.
                break;
            }
        }

        if(peak == true)  // 영역의 데이타가 모두 상승 경향일 경우 
        {
            // 영역데이타가 마지막 값 이후에 하락하는 경우 && threshold 값 이상일 경우 peak 일 수 있다. 
            if(beforeValue > imsi[count] && beforeValue > threshold) peakPos.Add(index + count - 1);  
        }
    }

    foreach(int pos in peakPos)  // 앞단에서 찾은 Peak 가능 값들을 다시 확인한다. 
    {
        Array.Copy(data, pos, imsi, 0, count);  // peak 예상 위치에서 카운트 만큼 데이타를 취한다. 
        var beforeValue = imsi[0];
        peak = true;

        for(int i = 1 ; i < count ; i++)
        {
            if(beforeValue > imsi[i]) beforeValue = imsi[i];  // 데이타가 계속 하강경향인지 확인한다. 
            else
            {
                peak = false;   // 중간에 값이 상승하면 peak가 아니다. 
                break;
            }
        }

        if(peak == true) peaks.Add(pos);
    }

    return peaks;
}

 

 

 

List<int> PeakDetect(in double[] data, int count, double threshold)

 

return : searching 된 모든 peak 위치값

param-1 : 데이타 

param-2 : 영역데이타의 카운트 ( 연속적인 상승 및 하강에 대한 정보를 확인하기 위한 데이타 영역 카운트)

                 카운트가 작으면 peak 의 작은 변화도 peak로 감지해 버린다. 

param-3 : searching 된 Peak 의 값이 threshold 이하인 경우 peak로 찾지 않고 제외한다. 

반응형

댓글()