Wyszukiwanie maximów funkcji periodycznej

0

Witam
Mam dane w pewnej tablicy ok powiedzmy 400 elementów. Są one ułożone tak, że ich wartości po naniesieniu na skalę(X-nr indeksu) przypominają funkcję okresową sinus, tzn rosną do danego maximum lokalnego, następnie maleją do min lokalnego i tak dalej. Okres funkcji sie zmiania, tzn maleje w miarę wzrostu indexu, maleje także amplituda wychyleń wraz ze wzrostem indexu. Zależy mi na znalezieniu indeksów z największymi wartościami lokalnymi, które będą dalej potrzebne do kolejnych analiz.Ma ktoś pomysł na realizacjętego? Pewnie można to zrobić przy pomocy pochodnej i analizy matematycznej, ale tutaj jest zmienny okres funcji i zmienna amplituda, więc może da radę zrobić to troszkę inaczej...
Dzieki za info
Pozdrawiam
M&S

0

Nie wiem czy dobrze zrozumiałem, ale jeśli tak, to to można zapisać mniej więcej tak:

i = 1, j = WIELKOSC_TABLICY;
aktualna_wartosc1 = tab[0];
while (i < j)
{
 aktualna_wartosc2 = tab[i++];
 aktualna_wartosc3 = tab[i];
 if ((aktualna_wartosc2 < aktualna_wartosc3) && (aktualna_wartosc2 < aktualna_wartosc1)) MIN_LOKALNE;
else
 if ((aktualna_wartosc2 > aktualna_wartosc3) && (aktualna_wartosc2 > aktualna_wartosc1)) MAX_LOKALNE;
}

To jest najprostsze. Można jeszcze popracować nad optymalizacją jeśli jest ważna, ale na PC nie jest to konieczne, bo to niewielka tablica.

Sam algorytm działa tak, że sprawdza trzy sąsiednie punkty. Jeśli środkowy z nich jest mniejszy jednocześnie od dwóch sąsiednich, to musi być minimum lokalnym, jeśli jest większy od sąsiadów do musi być maksimum lokalnym.

0

kurcze, jestem nie zarejestrowany i źle wpisałem... sorki... juz poprawiam

i = 0, j = WIELKOSC_TABLICY;
while (i < j)
{
 aktualna_wartosc1 = tab[i++];
 aktualna_wartosc2 = tab[i++];
 aktualna_wartosc3 = tab[i--];
 if ((aktualna_wartosc2 < aktualna_wartosc3) && (aktualna_wartosc2 < aktualna_wartosc1)) MIN_LOKALNE;
else
 if ((aktualna_wartosc2 > aktualna_wartosc3) && (aktualna_wartosc2 > aktualna_wartosc1)) MAX_LOKALNE;
}
0

A jak bardzo nieregularne są te wartości ? Mógłbyś podać kilka przykładów (najlepiej graficznie w postaci wykresu punktowego). Czy oscylują wokół stałej wartości ? Metoda zależy od charakterystyki tych punktów. Najlepiej będzie chyba najpierw poszukać okresu drgań - przybliżyć go jakąś funkcją ,albo przynajmniej odrzucić skrajne wartości. Wtedy łatwiej jest znaleźć ekstrema, bo wiadomo, że na każdy okres przypada jedno gdzieś pośrodku. No i jeszcze fajnie by było, jakbyś napisał skąd się biorą te punkty, dlaczego je badasz i pod jakim kątem, dlaczego szukasz maksimów, jak bardzo dokładna/wydajna musi być metoda.

0

Witam
Otóż owa tablica jest to tablica jasności pixeli bitmapy z zeskanowanego wzorca do badania rozdzielczości np:skanerów.Na poniższym linku znajduje sie zeskanowany wzorzec w formie czarnych pasków na białym tle o wzrastającym stopniu zagęszczenia linii(idąc w prawą stronę). Poniżej tego znajduje sie wykres jasności, 255 to kolor biały, czarny to 0 (standardowa paleta RGB).Analizę zaczynamy od lewej strony, amplituda jasności jest największa ponieważ jest tam najwięcej barwy białej, w miarę posuwania sie w prawą stronę wzrasta zagęszczenie linii oraz spada kontrast. Zależy mi na wyłapaniu lokalnych maximów oraz lokalnych minimów(na tej podstawie obliczam spadek kontrastu pomiędzy parą linia czarna-biała). Kontrast jest liczony w sposób taki ,że jeśli:
Cmax-maxymalna jasnośc barwy białej
Cmin-minimalna jasności barwy czarnej
to:
Kontrast=(Cmax-Cmin)/(Cmax+Cmin);
Jeśli kontrast spada o połowę jest to właśnie graniczna rozdzielczośc.
Zatem mając ową tablicę jasności o której pisałem o trzymuję taki wykres jak w linku, ale nie mam pomysłu jak wyłuskać wartości lokalnych pkt przegięć min i max.
Link do skanu wzorca oraz wykresu amplitud jasności:
http://cassis007.republika.pl/
JEśli będą potrzebne jakieś dodatkowe info napiszę. Pozdrawiam

0

No to ci podałem algorytm, tyle że tutaj widzę niedokładne wyjaśnienie... otóż minimum i maksimum lokalne występuje tutaj więcej razy niż normalnie można by sądzić, ponieważ w okolicy maks/min występują dodatkowe zafalowania. Algorytm który opisałem, pozwoli na wyłuskanie bez najmniejszego problemu wszystkich min/maks lokalnych, nie uwzględnia jedynie tych minimalnych zafalowań. Rozwiązaniem tego problemu mógłby być taki algorytm, w którym wyszukujesz maksymalny punkt dotąd dopóki nie zmienia się znak funkcji. Jak się zmienia to masz maks lokalne. Potem szukasz min lokalne do następnego przejścia znaków. Najmniejsza wartość będzie więc minimum lokalne. I powtarzasz dalej.
pseudokod:

i = 0 -> pozycja w tablicy
powtarzaj dopóki 'i' nie dojdzie do końca tablicy
{
   jeśli tab[i] > 0 to
   {
      //jesteśmy ponad osią, więc szukamy maks
      maks_lok = 0;
      powtarzaj dopóki 'i' nie dojdzie do końca tablicy lub tab[i] jest większe od zera
      {
         jeśli tab[i] > maks_lok to maks_lok = tab[i];
         i++;
      }
   }
   else
   {
      //jesteśmy pod osią (lub na osi) więc szukamy min
      min_lok = 0;
      powtarzaj dopóki 'i' nie dojdzie do końca tablicy lub tab[i] jest mniejsze od zera
      {
         jeśli tab[i] < min_lok to min_lok = tab[i];
         i++;
      }
   }
}

Tak mniej więcej wygląda pseudokod takiego algorytmu. Nie jest on trudny, więc można łatwo przenieść go na dowolny język. Ten algorytm pomija problem min/maks lokalnych jeśli występują dodatkowe zniekształcenia w okolicy maks/min.

0

Zapomniałem dodać, że jeśli wykres jest cały nad/pod osią to można od wszystkich punktów odjąć średnią wartość z całego zbioru. Wtedy powinien leżeć trochę nad osią i trochę pod.

0

A, czyli masz wzorzec. To zmienia całą sytuację. Jaka jest funkcja wzorca zatem. Tzn jaka funkcja opisywałaby idealny skaner. Na jej podstawie szukasz maksimów i minimów, tj. szukasz wartości maksymalnych i minimalnych próbki w pewnym otoczeniu tego argumentu, dla którego istnieje ekstremum w funkcji wzorcowej. Z lewej strony te otoczenia będą szersze, z prawej odpowiedni węższe. Za szerokość otoczenia można przyjąć jakieś 1/4 okresu (wykres przecina linie "środka" 2 x w ciągu 1 okresu), albo nawet całą 1/2 okresu

1 użytkowników online, w tym zalogowanych: 0, gości: 1