ByteRun jest również algorytmem kompresującym strumienia informacji. Tu również kompresujemy powtarzające się symbole w ciągu jednak z pewnymi usprawnieniami. Podczas kodowania łańcucha wejściowego mogą zdarzyć się nam dwie sytuacje:

  1. symbole następujące po sobie różnią się od siebie (przykładowo 1 2 3 4 5),
  2. symbole następujące po sobie są identyczne (przykładowo 1 1 1 1 1)

Sam kodogram w obu przypadkach wygląda podobnie. Na początku występuje liczba \(n\) a za nią następuje zakodowana informacja. Jeżeli \(n\in<0,127>\) to mamy do czynienia z pierwszym przypadkiem to po niej następuje \(n+1\) znaków przepisanych bez zmiany. Jeżeli zaś \(n\in<-127,-1>\) to mamy do czynienia z drugim przypadkiem i po liczbie \(n\) wystąpi tylko jeden znak, który po odkodowaniu powinien wystąpić \(-n+1\) razy. Na podstawie wzorów można łatwo wywnioskować, że maksymalna długość jednej paczki informacji, jaką możemy spakować, nie będzie większa niż ~\(128\) znaków.

Przykład:

Wiadomość: [5,5,5,1,2,3,4,4,1,2,3,4]

Kodogram: [-2,5,2,1,2,3,-1,4,3,1,2,3,4]

Uprzedzając pytania: tak w nie sprzyjających okolicznościach tu też zakodowana wiadomość może mieć mniej bajtów przed kompresją niż po niej. Wiec też można złożyć ten najbardziej niekorzystny buffor:

np.zeros(np.prod(data.shape)*2)

Warto napisać sobie dwie funkcje pomocnicze do przeszukiwania zbioru przy użyciu zwykłego fora z break (nie np.where), które znacząco ułatwią prace nad implementacją tego algorytmu:

  • Pierwsza: znajdowanie jak długo elementy się powtarzają,
  • druga: znajdowanie jak długo elementy są różne, czy tak długo aż nie znajdzie się para elementów identycznych jeden za drugim (czyli x[i]==x[i+1]).

Podczas kompresji zaczynamy od sprawdzenia, czy bieżący element jest identyczny z następnym — wtedy wykorzystujemy funkcję pierwszą, a jeżeli nie to uruchamiamy funkcję drugą. Potem sprawdzamy, czy licznik jest większy niż 128 i jeżeli tak to zapisujemy fragmenty. Do tego można wykorzystać pętlę while:

while licznik >128:
    #zapis
    licznik -=128
#zapis

Sam #zapis będzie się różnił w zależności, czy znaki się powtarzają lub różnią. Trzeba to zastąpić odpowiednim kodem na bazie informacji z początku tej części instrukcji.