<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl">
	<id>http://brain.fuw.edu.pl/edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Magdaz</id>
	<title>Brain-wiki - Wkład użytkownika [pl]</title>
	<link rel="self" type="application/atom+xml" href="http://brain.fuw.edu.pl/edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Magdaz"/>
	<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php/Specjalna:Wk%C5%82ad/Magdaz"/>
	<updated>2026-04-05T18:00:41Z</updated>
	<subtitle>Wkład użytkownika</subtitle>
	<generator>MediaWiki 1.34.1</generator>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=Pracownia_Sygna%C5%82%C3%B3w_Biologicznych/Zajecia_8&amp;diff=6831</id>
		<title>Pracownia Sygnałów Biologicznych/Zajecia 8</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=Pracownia_Sygna%C5%82%C3%B3w_Biologicznych/Zajecia_8&amp;diff=6831"/>
		<updated>2017-04-03T13:29:39Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Dodatkowa lektura */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;b&amp;gt;Reakcja skórno-galwaniczna&amp;lt;/b&amp;gt;&lt;br /&gt;
==Wstęp==&lt;br /&gt;
Reakcja skórno-galwaniczna (ang. ''galvanic skin response'' &amp;amp;mdash; GSR), nazywana czasami reakcją elektrodermalną, reakcją elektryczną skóry, reakcją psychogalwaniczną, jest zmianą właściwości elektrycznych skóry pod wpływem stanu psychologicznego. Wielkością mierzoną jest oporność skóry lub odwrotność oporności, czyli przewodnictwo. Z definicji oporu elektrycznego, opór (''R'') jest równy stosunkowi napięcia (''V'') do prądu przepływającego przez opór: ''R'' = ''V''/''I''. &lt;br /&gt;
Wzmacniacz podaje stałe napięcie pomiędzy elektrodami i mierzy natężenie przepływającego prądu elektrycznego. Na podstawie zmian natężenia prądu, wyznaczamy zmiany w przewodnictwie skóry. W zapisie przewodnictwa skóry możemy wyróżnić składową stałą (tzw. ''baseline level'') oraz składową zmienną, reagującą na różne rodzaje bodźców zewnętrznych. Składową zmienną nazywa się czasem reakcją GSR i my też będziemy stosować od tej pory to pojęcie. Przykład reakcji GSR jest pokazany na&lt;br /&gt;
&amp;lt;xr id=&amp;quot;fig:GSR&amp;quot;&amp;gt;rys. %i&amp;lt;/xr&amp;gt;&lt;br /&gt;
[[Plik:Gsr.svg|250px|thumb|right|&amp;lt;figure id=&amp;quot;fig:GSR&amp;quot;&amp;gt;&amp;lt;/figure&amp;gt; Reakcja skórno-galwaniczna w sygnale 60 s. Sygnał był mierzony pomiędzy palcem środkowym i wskazującym.]]&lt;br /&gt;
Również przy braku bodźców zewnętrznych obserwuje się spontaniczne reakcje GSR występujące z typową częstością 1-3/minutę. Parametrami do opisu reakcji GSR są:&lt;br /&gt;
* Amplituda: różnica pomiędzy składową stałą a wartością GSR w maksimum odpowiedzi&lt;br /&gt;
* Opóźnienie (latencja): czas pomiędzy bodźcem a początkiem odpowiedzi. Typowe wartości: 3 sekundy lub mniej.&lt;br /&gt;
* Czas narastania: czas pomiędzy początkiem odpowiedzi GSR a jej maksimum. Typowe wartości: 1-3 sekundy.&lt;br /&gt;
* Czas połowicznego zaniku: czas pomiędzy maksimum odpowiedzi GSR i punktem, w którym wartość odpowiedzi malej o połowę. Typowe wartości: 2-10 sekund.&lt;br /&gt;
&lt;br /&gt;
Najbardziej uznany model reakcji GSR zakłada, że wzrost przewodnictwa skóry następuje w wyniku wydzielania potu i wypełniania duktów potowych w skórze. Przewodnictwo wraca do poziomu odniesienia, gdy płyn wydzielony na powierzchnię skóry jest z powrotem wchłonięty przez gruczoły potowe. W modelu tym, dukty potowe odgrywają rolę zmiennych oporników. Ich opór maleje wraz z wypełnieniem. Amplituda GSR zależy od ilości potu dostarczonego do duktów oraz od liczby pobudzonych gruczołów potowych. Np. w skórze dłoni występuje ponad 2000 gruczołów potowych w jednym cm&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Aktywacja kanałów potowych jest kontrolowana przez część współczulną autonomicznego układu nerwowego. Gruczoły potowe dostają cholinergiczne wejścia, które zmieniają napięcie błonowe komórek i regulują ich aktywność. W związku z elektryczną naturą procesów kontroli i działania gruczołów potowych, ich funkcjonowanie może być rejestrowane w postaci potencjałów elektrycznych, podobnie jak zapisy EKG czy EMG.&lt;br /&gt;
&lt;br /&gt;
==Eksperymenty Junga i Mathisona==&lt;br /&gt;
Pierwsze opisy zastosowania aparatury GSR w psychoanalizie pojawiły się w książce Carla Gustava Junga, dotyczącej analizy słów. Osoba badana podłączona była do aparatury mierzącej zmiany przewodnictwa skóry, poprzez elektrody umieszczone na dłoni. Słowa z listy były czytane na głos osobie badanej. Jeśli słowo zawierało ładunek emocjonalny, powodowało ono zmianę przewodnictwa skóry i wychylenie się igły galwanometru. Wszystkie słowa które powodowały odpowiedź odbiegającą znacznie od normy były wskazaniem na możliwe obszary konfliktu wewnętrznego u pacjenta. Jung wykorzystywał reakcje GSR jako metodę dodatkową, wspomagającą jego własne obserwacje dotyczące źródeł konfliktów wewnętrznych u pacjentów.&lt;br /&gt;
Konstrukcja przenośnych wzmacniaczy do GSR spowodowała wzrost zainteresowania tą metodą i jej wykorzystanie jako &amp;amp;bdquo;detektor kłamstw&amp;amp;rdquo;. Podstawą ich działania jest założenie, ze odpowiedź na pytanie niezgodnie z prawdą powoduje wewnętrzny konflikt i reakcje układu autonomicznego, która nie podlega kontroli świadomości. W praktyce, w sądownictwie, badanie detektorem kłamstw nie jest uznawane za dowód. Wykorzystując detektor kłamstw, Volney Mathison zauważył, że niektóre wspomnienia lub zmiany nastroju powodują znaczną reakcje GSR. Opracował on listę słów używaną w połączeniu z pomiarem GSR. Przy niektórych słowach pojawiała się bardzo silna reakcja GSR, która wskazywała, że dane słowo jest powiązane z silnymi emocjami mającymi swoje korzenie w podświadomości. Najczęściej, badany zupełnie nie zdawał sobie sprawy, że wywołał tak silną reakcję w układzie pomiarowym.&lt;br /&gt;
&lt;br /&gt;
==Biofeedback==&lt;br /&gt;
Biofeedback (biologiczne sprzężenie zwrotne) jest techniką samoregulacji. Na podstawie pomiaru stanu fizjologicznego osoby badanej i dostarczania mu zwrotnej informacji o jego zmianach, osoba badane może nauczyć się świadomie modyfikować funkcje, które normalnie nie są kontrolowane świadomie. Zastosowanie pomiaru przewodnictwa skóry w biofeedbacku opiera się na następujących obserwacjach:&lt;br /&gt;
* Niski poziom pobudzenia kory mózgowej jest potrzebny do odczuwania stanu relaksu, w stanie hipnozy oraz do lepszego odczuwania swojej nieświadomości.&lt;br /&gt;
* Wysoki poziom pobudzenia kory mózgowej zapewnia szybszy refleks, koncentrację, zdolność szybszego czytania i lepszego zapamiętywania.&lt;br /&gt;
* Poziom pobudzenia kory mózgowej i przewodnictwo skóry są ze sobą związane. Pobudzenie kory mózgowej jest odzwierciedlone we wzroście przewodnictwa skóry, a obniżenie poziomu pobudzenia kory mózgowej jest związane z obniżeniem przewodnictwa skóry.&lt;br /&gt;
&lt;br /&gt;
Za pomocą czułej metody mierzącej i przekazującej poziom pobudzenia, może on być świadomie kontrolowany w szerokim zakresie. Metoda ta jest wykorzystywana w psychologii, medycynie, sporcie i biznesie.&lt;br /&gt;
==Dodatkowa lektura==&lt;br /&gt;
 Polecamy zapoznanie się z rozdziałem 27 książki dostępnej pod adresem [http://www.bem.fi/book/].&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
===Ćwiczenie I (Pomiar składowej stałej i habituacja)===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wykonaj pomiar GSR dwoma metodami.&lt;br /&gt;
* Parą elektrod bipolarnych do EMG umieszczonych na zewnętrznej i wewnętrznej stronie dłoni. Elektrodę referencyjną umieść np. na brzuchu.&lt;br /&gt;
* Parą elektrod do GSR. Użyj kabla do pomiaru GSR z pięcioma stykami. Na elektrody do GSR nałóż żel w punkcie metalowego kontaktu. Załóż elektrody na palec wskazujący i środkowy. Kontakty powinny znajdować się po wewnętrznej stronie dłoni, gdyż jest tam większa ilość kanałów potowych. &lt;br /&gt;
* Skonfiguruj program do rejestracji i przeglądania mierzonego sygnału w czasie rzeczywistym.&lt;br /&gt;
* Opisz rejestrowane sygnały.&lt;br /&gt;
* Wykonaj eksperyment. Gdy osoba badana siedzi spokojnie i bez poruszania się, druga osoba zadaje mu pytanie &amp;amp;bdquo;Czy masz na imię X&amp;amp;rdquo;, gdzie X oznacza prawdziwe imię. Badany odpowiada &amp;amp;bdquo;Tak&amp;amp;brdquo;, po każdym pytaniu. Po powrocie sygnału do poziomu odniesienia, druga osoba ponownie zadaje mu pytanie. Proces zadawania pytań trwa tak długo, dopóki badany nie wykaże reakcji w sygnale, przez trzy kolejne pytania. Brak reakcji w sygnale nazywa się habituacją.&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie II (Pomiar składowej zmiennej)===&lt;br /&gt;
W tym samym układzie doświadczalnym jak w Ćwiczeniu I wykonaj następujący eksperyment.&lt;br /&gt;
&lt;br /&gt;
* Przekaż osobie badanej, siedziała spokojnie i odpowiadała na zadawane pytanie &amp;amp;bdquo;Tak&amp;amp;rdquo; lub &amp;amp;bdquo;Nie&amp;amp;rdquo;.&lt;br /&gt;
* Podłącz trigger. Rozpocznij rejestrację sygnału.&lt;br /&gt;
* Zadawaj po kolei pytania z listy poniżej. Moment zadania każdego pytania zaznacz przez wciśniecie triggera. Po zadaniu pytania obserwuj reakcje skórno-galwaniczną. Poczekaj aż przewodnictwo wróci do poziomu odniesienia, zanim zadasz następne pytanie. &lt;br /&gt;
* Gdy zadasz wszystkie pytania i zapiszesz ostatnią reakcję zatrzymaj rejestrację.&lt;br /&gt;
* Dla każdej odpowiedzi GSR oszacuj latencję, amplitudę, czas narastania i czas połowicznego zaniku. Zbadaj rozrzut wyników. Jeśli odpowiedzi są podobne, uśrednij wyniki i wyznacz średnią latencję, amplitudę, czas narastania i czas połowicznego zaniku.&lt;br /&gt;
&lt;br /&gt;
Lista pytań:&lt;br /&gt;
# Czy mieszkasz w Warszawie?&lt;br /&gt;
# Czy lubisz brokuły?&lt;br /&gt;
# Czy masz kota?&lt;br /&gt;
# Czy urodziłeś/aś się w Polsce?&lt;br /&gt;
# Czy jeździsz na łyżwach?&lt;br /&gt;
# Czy masz brata?&lt;br /&gt;
# Czy byłeś/aś w Hiszpanii?&lt;br /&gt;
# Czy studiujesz na UW?&lt;br /&gt;
# Czy dzisiaj jest wtorek?&lt;br /&gt;
# Czy lubisz pizzę?&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie III (Analiza składowej zmiennej dla obrazów z zawartością neutralną i emocjonalną)===&lt;br /&gt;
W tym samym układzie doświadczalnym jak w Ćwiczeniu I i II wykonaj następujący eksperyment.&lt;br /&gt;
* Przekaż osobie badanej, by siedziała spokojnie.&lt;br /&gt;
* Rozpocznij rejestrację sygnału&lt;br /&gt;
* Uruchom program ..... wyświetlający losowo obrazy o zawartości neutralnej i emocjonalnej. Wyświetlaj obrazki naciskając klawisz klawiatury. Po wyświetleniu obrazka obserwuj reakcje skórno-galwaniczną. Poczekaj aż przewodnictwo wróci do poziomu odniesienia, zanim wyświetlisz następny obrazek.&lt;br /&gt;
* Gdy pojawi się napis &amp;amp;bdquo;Koniec&amp;amp;rdquo;, odczekaj 10 sekund i zatrzymaj rejestrację.&lt;br /&gt;
* Odczytaj momenty wyświetlania obrazów neutralnych i emocjonalnych zapisane przez program. Na podstawie tych danych, dla każdej odpowiedzi na obraz emocjonalny oszacuj latencję, amplitudę, czas narastania bez czasu połowicznego zaniku. Zbadaj rozrzut wyników. Jeśli odpowiedzi są podobne, uśrednij wyniki i wyznacz średnią latencję, amplitudę, czas narastania.&lt;br /&gt;
*Porównaj uśrednione parametry odpowiedzi GSR dla obrazów emocjonalnych i słów neutralnych otrzymanych w Ćwiczeniu II.&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=Pracownia_Sygna%C5%82%C3%B3w_Biologicznych/Zajecia_2_4&amp;diff=6531</id>
		<title>Pracownia Sygnałów Biologicznych/Zajecia 2 4</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=Pracownia_Sygna%C5%82%C3%B3w_Biologicznych/Zajecia_2_4&amp;diff=6531"/>
		<updated>2017-03-02T21:11:49Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Ćwiczenia */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Rejestracja i analiza sygnału EKG==&lt;br /&gt;
[[Plik:einthoven_ekg.png|250px|thumb|right|&amp;lt;figure id=&amp;quot;fig:einthoven_ekg&amp;quot;&amp;gt;&amp;lt;/figure&amp;gt; Aparat do rejestracji czynności elektrycznej serca skonstruowany przez W. Einthovena. Proszę zauważyć w jakich miejscach na ciele zbierana jest sygnał.]]&lt;br /&gt;
[[Plik:ekg_animacja.gif|250px|thumb|right|&amp;lt;figure id=&amp;quot;fig:ekg_animacja&amp;quot;&amp;gt;&amp;lt;/figure&amp;gt; Rozchodzenie się sygnału stymulujacego pracę serca i związane z tym powstawanie sygnału EKG. Rysunek po brany ze strony Wikipedii.]]&lt;br /&gt;
[[Plik:ekg_opis.png|250px|thumb|right|&amp;lt;figure id=&amp;quot;fig:ekg_opis&amp;quot;&amp;gt;&amp;lt;/figure&amp;gt; Oznaczenia kolejnych składowych sygnału EKG.]]&lt;br /&gt;
[[Plik:wilson.png|250px|thumb|right|&amp;lt;figure id=&amp;quot;fig:wilson&amp;quot;&amp;gt;&amp;lt;/figure&amp;gt; Umiejscowienie elektrod do pomiaru czynności elektrycznej serca z powierzchni klatki piersiowej, rysunek pobrany ze stron Wikipedii.]]&lt;br /&gt;
 &lt;br /&gt;
Mechanizm powstawania czynności elektrycznej serca został omówiony na zajęciach &amp;amp;bdquo;Sygnały Bioelektryczne&amp;quot;. W tym miejscu przypomnimy tylko kilka ważnych (i ciekawych) faktów.&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt; Czynność elektryczna serca znana jest od połowy XIX, jednakże za początek narodzin elektrokardiografii uznaje się rok 1903, kiedy to W. Einthoven dokonał pomiaru czynności elektrycznej serca z powierzchni ciała (&amp;lt;xr id=&amp;quot;fig:einthoven_ekg&amp;quot;&amp;gt;rys. %i&amp;lt;/xr&amp;gt;). Jako metoda diagnostyczna, elektrokardiografia zaczęła się szybko rozwijać po roku 1936, kiedy to do rejestracji czynności elektrycznej serca zastosowano wzmacniacz lampowy oraz system zapisu pomiaru na papierze.&lt;br /&gt;
&amp;lt;li&amp;gt; Serce posiada specjalny, wzbudzany samoczynnie układ, który generuje i przewodzi bodźce elektryczne. Następstwem działania tego układu jest rytmiczna praca serca o częstości od 70 do 180 cykli na minutę (częstość ta ulega zmianom pod wpływem czynników biochemicznych, powstałych np. w skutek stresu).&lt;br /&gt;
&amp;lt;li&amp;gt; Elektroda rejestrująca sygnał EKG zbiera czynność elektryczną wszystkich komórek serca, a zatem zarówno komórek wchodzących w skład układu generującego i przewodzącego impulsy elektryczne oraz kurczących się pod wpływem impulsów sterujących mięśni, które kurcząc się, również wytwarzają sygnał elektryczny. Jednakże, z uwagi na nieporównywalnie dużo większą masę mięśni serca w porównaniu z masą komórek układu stymulującego przyjmuje się, że głównym składnikiem sygnału EKG jest czynność elektryczna mięśnia sercowego.&lt;br /&gt;
&amp;lt;li&amp;gt; W przybliżeniu, sygnał stymulujący pracę serca rozchodzi się z jego prawej górnej części w kierunku dolnym i na lewą stronę. Na skutek pobudzania kolejnych partii mięśnia sercowego, powstaje charakterystyczny kształt sygnału EKG (&amp;lt;xr id=&amp;quot;fig:ekg_animacja&amp;quot;&amp;gt;rys. %i&amp;lt;/xr&amp;gt;, &amp;lt;xr id=&amp;quot;fig:ekg_opis&amp;quot;&amp;gt;rys. %i&amp;lt;/xr&amp;gt;). &lt;br /&gt;
&amp;lt;li&amp;gt; Oznaczenia kolejnych składowych sygnału EKG:&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt; odchylenia od linii poziomej (izoelektrycznej) nazywamy załamkami,&lt;br /&gt;
&amp;lt;li&amp;gt; odległość w czasie pomiędzy końcem załamka P i początkiem załamka Q oraz końcem załamka S i początkiem załamka T nazywamy odcinkami &amp;amp;mdash; odpowiednio PQ i ST.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Elektrody pomiarowe połączone do aparatury rejestrujących nazywamy odprowadzeniami. Uwaga &amp;amp;mdash; przyjęto odprowadzeniami oznaczać także sygnały EKG będące liniowymi kombinacjami sygnałów zebranych przez elektrody.&lt;br /&gt;
&amp;lt;li&amp;gt; W konwencjonalnej elektroencefalografii stosuje się 12 tzw. odprowadzeń klasycznych:&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt; Trzy odprowadzenia kończynowe biegunowe, zaproponowane jeszcze przez Einthoven i oznaczane rzymskimi cyframi I, II i III. Elektrody w tym systemie umieszcza się prawej (R) (ang. ''right'') i lewej (L) (ang. ''left'') kończynie górnej (najczęściej w okolicy nadgarstka, czasem ramieniu lub czy barku) oraz lewej nodze w okolicy stopy (F) (ang. ''foot''). Elektrodę umieszczaną na prawym nadgarstku oznacza się kolorem czerwonym, na lewym żółtym, na lewej kostce zielonym. Elektrodę masy umieszcza się zwykle na lewej kostce (choć teoretycznie można ją aplikować gdziekolwiek) i jest ona oznaczona kolorem czarnym. Odprowadzenia kończynowe mierzą różnicę napięć pomiędzy miejscami przyłożenia elektrod w następujący sposób:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;equation id = &amp;quot;eq_1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{ll}&lt;br /&gt;
I   &amp;amp; = V_{L} - V_{R} \\&lt;br /&gt;
II  &amp;amp; = V_{F} - V_{R} \\&lt;br /&gt;
III &amp;amp; = V_{F} - V_{L}&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
gdzie: &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;V_{R}, V_{L}, V_{F}&amp;lt;/math&amp;gt; to potencjały odpowiednio na prawym i lewym nadgarstku oraz stopie mierzone względem elektrody masy.&amp;lt;br/&amp;gt;&lt;br /&gt;
Jak łatwo zauważyć, tylko dwa spośród powyższych napięć są liniowo niezależne, co można zapisać w postaci związku:&lt;br /&gt;
&amp;lt;equation id = &amp;quot;eq_2&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;I + III = II&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
który nazywany jest prawem Einthovena. Proszę zauważyć, iż w tym przypadku wzmacniane jest sygnał będący różnicą napięć dwóch kolejnych elektrod, stąd też te odprowadzenia nazywamy dwubiegunowymi (bipolarnymi).&lt;br /&gt;
&amp;lt;li&amp;gt; Trzy odprowadzenia jednobiegunowe Goldberga. W odprowadzeniach tych sygnał w danym odprowadzeniu jest różnicą napięć pomiędzy elektrodą pomiarową a średnim napięciem na dwóch pozostałych elektrodach:&lt;br /&gt;
&amp;lt;equation id = &amp;quot;eq_3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{ll}&lt;br /&gt;
aV_{L} &amp;amp; = V_{L} - \frac{V_{R}+V_{F}}{2} \\&lt;br /&gt;
aV_{R} &amp;amp; = V_{R} - \frac{V_{L}+V_{F}}{2} \\&lt;br /&gt;
aV_{F} &amp;amp; = V_{F} - \frac{V_{L}+V_{R}}{2}&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Sześć odprowadzeń jednobiegunowych Wilsona. W przypadku warto zapoznać się z z historią tych odprowadzeń. Początkowo Wilson zaproponował układ jednobiegunowych doniesień dla kończyn w następujący sposób:&lt;br /&gt;
&amp;lt;equation id = &amp;quot;eq_4&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{ll}&lt;br /&gt;
V_{LW} &amp;amp; = V_{L} - \frac{V_{R}+V_{L}+ V_{F}}{3} \\&lt;br /&gt;
V_{RW} &amp;amp; = V_{R} - \frac{V_{R}+V_{L}+ V_{F}}{3} \\&lt;br /&gt;
V_{FW} &amp;amp; = V_{F} - \frac{V_{R}+V_{L}+ V_{F}}{3}&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
Jak widzimy, jako elektrodę odniesienia wybrał on średnie napięcie rejestrowane przez elektrody. Niestety, sygnały prezentowane w tym systemie miały małą amplitudę, w związku z czym tego rodzaju odprowadzenia nie stosowano w praktyce. Z systemu zaproponowanego przez Wilsona wywodzi się jednak system odniesień Goldbergera, który zauważył, że napięcie na trzeciej kończynie można zwiększyć o 50% jeśli do wyznaczenia napięcia odniesienia zastosuje się dwie, a nie trzy elektrody. Metoda wyznaczania potencjału odniesienia zaproponowana przez Wilsona znalazła jednak zastosowanie przy mierzeniu czynności elektrycznej serca mierzonej z powierzchni klatki piersiowej. W tym celu elektrody umieszcza się w pewnych ustalonych miejscach (&amp;lt;xr id=&amp;quot;fig:wilson&amp;quot;&amp;gt;rys. %i&amp;lt;/xr&amp;gt;, zaś odprowadzenia oznacza się symbolami &amp;lt;math&amp;gt;V_1, V_2, \dots, V_6&amp;lt;/math&amp;gt;. Odniesieniem w tym przypadku jest średni sygnał rejestrowany na kończynach górnych i lewej stopie. &lt;br /&gt;
&amp;lt;/ul&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
&lt;br /&gt;
Aby uruchomić zbieranie sygnału należy wykonać następujące operacje:&lt;br /&gt;
* przykleić elektrody do badanego;&lt;br /&gt;
* włożyć przewody do elektrod, a potem do wzmacniacza;&lt;br /&gt;
* podłączyć zasilanie wzmacniacza;&lt;br /&gt;
* podłączyć wzmacniacz do komputera (przejściówka optyczna i kabel USB);&lt;br /&gt;
* otworzyć Terminal i wpisać polecenia:&lt;br /&gt;
** &amp;lt;tt&amp;gt;obci launch ../administrator/obci/scenarios/porti7_ekg.ini&amp;lt;/tt&amp;gt;. Po tym poleceniu wzmacniacz powinien wyświetlać napis &amp;amp;bdquo;Fiber&amp;amp;rdquo;; napis &amp;amp;bdquo;Connect&amp;amp;rdquo; oznacza, że połączenie wzmacniacza z komputerem nie udało się. W takim przypadku wykonujemy polecenie &amp;lt;tt&amp;gt;obci srv_kill&amp;lt;/tt&amp;gt; i powtarzamy próbę połączenia.&lt;br /&gt;
** &amp;lt;tt&amp;gt;svarog&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;Ćwiczenie 1: Podaj związek pomiędzy sygnałami mierzonymi w systemie Goldbergera, a systemem Einthovena. Podaj analogiczny związek pomiędzy sygnałami w odniesieniach Goldberga co ''Prawo Einthovena''. Pokaż, że w systemie Goldbergera uzyskuje się sygnały o amplitudzie o 50% wyższej niż w pierwotnym systemie Wilsona. &lt;br /&gt;
&lt;br /&gt;
;Ćwiczenie 2: Umieść po jednej elektrodzie na prawej i lewej kończynie górnej oraz w okolicy kostki na lewej nodze. Elektrodę GND umieść na brzuchu i podłącz ją do wejścia GND wzmacniacza. Elektrody pomiarowe podłącz do unipolarnych wejść wzmacniacza. Uruchom aplikację SVAROG do rejestracji i oglądania sygnałów bioelektrycznych. Korzystając zakładki &amp;amp;bdquo;Montaż&amp;amp;rdquo; utwórz I i II odprowadzenia Einthovena. Spróbuj zaobserwować sygnał EKG. Jeśli Ci się to nie udało, podaj przyczynę i zaproponuj rozwiązanie. Zaprojektuj filtr górnoprzepustowy i zastosuj go do zbieranego sygnału. Znajdź w sygnale EKG poszczególne załamki. &lt;br /&gt;
&lt;br /&gt;
;Ćwiczenie 3: &amp;lt;!--Obok elektrod umieszczonych na prawym i lewym nadgarstku w poprzednim ćwiczeniu doklej kolejne dwie elektrody i połącz je tym razem do wejścia bipolarnego wzmacniacza. Porównaj uzyskany sygnał z sygnałem rejestrowanym z elektrod monopolarnych.&lt;br /&gt;
&lt;br /&gt;
;Ćwiczenie 4: Odłącz elektrody od wejścia bipolarnego. --&amp;gt;Za pomocą elektrod połączonych z wejściami monopolarnymi zbierz sygnał EKG w odniesieniu Goldbergera.&lt;br /&gt;
&lt;br /&gt;
;Ćwiczenie 5: Zbierz fragment sygnału EKG przy pomocy Svaroga. Napisz program który:&lt;br /&gt;
* wczytuje i rysuje sygnał,&lt;br /&gt;
* transformuje sygnał do systemu dwubiegunowego i sprawdza dla niego prawo Einthovena&lt;br /&gt;
&lt;br /&gt;
;Ćwiczenie 6: Zaproponuj metodę rozpoznawania początku kolejnego cyklu pracy serca. Wyznacz widmo sygnału EKG, zebranego w ćwiczeniu 5 w kolejnych cyklach pracy serca.&lt;br /&gt;
&lt;br /&gt;
;Ćwiczenie 7: Napisz program, który wczyta plik z sygnałem i na jego podstawie wyznaczy tętno (ang. ''heart rate'').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--;Ćwiczenie 8: Wykorzystując poniższe fragmenty kodu, stwórz program, który będzie wyrysowywał zmiany tętna w czasie rzeczywistym.&lt;br /&gt;
Pierwszy fragment kodu, to moduł buforujący sygnał, drugi to moduł pobierający dane z bufora. Należy dopisać do modułu pobierającego dane z bufora przetwarzanie ich (wyrysowywanie tętna) we wskazanym miejscu. &lt;br /&gt;
Uruchamianie całości będzie polegało na:&lt;br /&gt;
* uruchomieniu wzmacniacza&lt;br /&gt;
* uruchomieniu modułu &amp;lt;tt&amp;gt;signal_catcher.py&amp;lt;/tt&amp;gt;&lt;br /&gt;
* uruchomienie &amp;lt;tt&amp;gt;heartrate.py&amp;lt;/tt&amp;gt;, ktory jest dostepny [http://escher.fuw.edu.pl/~mm/zajecia/heartrate.py tu], po wstawieniu do niego w odpowiednie miejsce oznaczone w komentarzu własnego kodu obliczającego tętno.&lt;br /&gt;
* Trochę zmieniona wersja &amp;amp;mdash; [http://escher.fuw.edu.pl/~mm/zajecia/heartrate_new.py &amp;lt;tt&amp;gt;heartrate_new.py&amp;lt;/tt&amp;gt;] oraz  [http://escher.fuw.edu.pl/~mm/zajecia/signal_catcher_pracownia.py &amp;lt;tt&amp;gt;signal_catcher_pracownia.py&amp;lt;/tt&amp;gt;]&lt;br /&gt;
(moduły importują inne moduły, więc trzeba się upewnić że zmienna środowiskowa &amp;lt;tt&amp;gt;PYTHONPATH&amp;lt;/tt&amp;gt; ma odpowiednią wartość, w szczególności musi się w niej znaleźć ścieżka do &amp;lt;tt&amp;gt;azouk-libraries/build/&amp;lt;/tt&amp;gt; aby można było zaimportować moduł &amp;lt;tt&amp;gt;multiplexer&amp;lt;/tt&amp;gt;. Eksportować ścieżki można np tak:&lt;br /&gt;
&amp;lt;tt&amp;gt;export PYTHONPATH=./:openbci/:azouk-libraries/build/:PYTHONPATH&amp;lt;/tt&amp;gt;, tzn. dodajemy ścieżki oddzielone dwukropkiem, tylko należy się upewnić, że dodajemy odpowiednie ścieżki)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
# signal_catcher.py&lt;br /&gt;
&lt;br /&gt;
import time&lt;br /&gt;
from multiplexer.multiplexer_constants import peers, types&lt;br /&gt;
from multiplexer.clients import BaseMultiplexerServer&lt;br /&gt;
import collections, variables_pb2&lt;br /&gt;
&lt;br /&gt;
class SignalCatcher(BaseMultiplexerServer):&lt;br /&gt;
    def __init__(self, addresses):&lt;br /&gt;
        super(SignalCatcher, self).__init__(addresses=addresses, type=peers.SIGNAL_CATCHER)&lt;br /&gt;
        self.number_of_channels = len(self.conn.query(message=&amp;quot;AmplifierChannelsToRecord&amp;quot;, type=types.DICT_GET_REQUEST_MESSAGE).message.split(&amp;amp;rdquo; &amp;amp;bdquo;))&lt;br /&gt;
        self.buffer = [collections.deque() for z in range(self.number_of_channels)]&lt;br /&gt;
        self.buffer_size = int(self.conn.query(message=&amp;quot;SignalCatcherBufferSize&amp;quot;, type=types.DICT_GET_REQUEST_MESSAGE).message)&lt;br /&gt;
&lt;br /&gt;
    def add(self, value):&lt;br /&gt;
        sampleVector = variables_pb2.SampleVector()&lt;br /&gt;
        sampleVector.ParseFromString(value)&lt;br /&gt;
&lt;br /&gt;
        i = 0&lt;br /&gt;
        for s in values:&lt;br /&gt;
            self.buffer[i].append(s)&lt;br /&gt;
            if len(self.buffer[i]) &amp;gt; self.buffer_size:&lt;br /&gt;
                self.buffer[i].popleft()&lt;br /&gt;
            i += 1&lt;br /&gt;
      &lt;br /&gt;
    def handle_message(self, mxmsg):&lt;br /&gt;
        if mxmsg.type == types.SIGNAL_CATCHER_REQUEST_MESSAGE:&lt;br /&gt;
            vector = variables_pb2.SampleVector()&lt;br /&gt;
            ind = int(mxmsg.message)&lt;br /&gt;
            &lt;br /&gt;
            for i in range(len(self.buffer[ind])):&lt;br /&gt;
                s = vector.samples.add()&lt;br /&gt;
                s.CopyFrom(self.buffer[ind][i])&lt;br /&gt;
            m = vector.SerializeToString()&lt;br /&gt;
            self.send_message(message = m, type = types.SIGNAL_CATCHER_RESPONSE_MESSAGE)&lt;br /&gt;
        elif mxmsg.type == types.AMPLIFIER_SIGNAL_MESSAGE:&lt;br /&gt;
            self.add(mxmsg.message)&lt;br /&gt;
            self.no_response()&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;amp;bdquo;__main__&amp;quot;:&lt;br /&gt;
    SignalCatcher(settings.MULTIPLEXER_ADDRESSES).loop()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* próba obejrzenia zmiany tętna po wysiłku fizycznym, bądź w spoczynku--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=Laboratorium_EEG/CSP&amp;diff=5256</id>
		<title>Laboratorium EEG/CSP</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=Laboratorium_EEG/CSP&amp;diff=5256"/>
		<updated>2016-05-17T11:34:33Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Filtry przestrzenne dla SSEP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Laboratorium_EEG]]/BSS&lt;br /&gt;
=Ślepa separacja źródeł=&lt;br /&gt;
Rozważmy ''N''-kanałowy sygnał EEG.&lt;br /&gt;
Próbkę tego sygnału możemy przedstawić jako punkt w przestrzeni rozpiętej przez osie, z których każda reprezentuje wartość potencjału w jednym kanale. Cały sygnał tworzy w tej przestrzeni chmurę punktów. Rozciągłość tej chmury w danym kierunku mówi nam o wariancji (zmienności) sygnału w tym kierunku. &lt;br /&gt;
&lt;br /&gt;
Taki zbiór punktów wygodniej jest analizować w układzie współrzędnych zgodnym z osiami głównymi macierzy kowariancji.&lt;br /&gt;
W dalszej części rozważań założymy, że te przestrzenie, w których rozważamy sygnały są przestrzeniami wektorowymi, a pojedyncze próbki wielokanałowego sygnału są wektorami. &lt;br /&gt;
[[Plik:Kowariancja.png|200px|center]]&lt;br /&gt;
&lt;br /&gt;
==Filtry przestrzenne i ślepa separacja źródeł==&lt;br /&gt;
Sygnał EEG jest superpozycją aktywności elektrycznej wielu źródeł.&lt;br /&gt;
Jak można estymować aktywność samych źródeł?&lt;br /&gt;
[[Plik:Mieszanie.png|200px|center]]&lt;br /&gt;
Niech:&lt;br /&gt;
: &amp;lt;math&amp;gt;s(t)&amp;lt;/math&amp;gt; - aktywność niezależnych źródeł,&lt;br /&gt;
: &amp;lt;math&amp;gt;x(t)&amp;lt;/math&amp;gt; mierzony sygnał&lt;br /&gt;
: &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; macierz przejścia taka, że:&lt;br /&gt;
::&amp;lt;math&amp;gt;x(t) = A s(t)&amp;lt;/math&amp;gt; (*)&lt;br /&gt;
:&amp;lt;math&amp;gt;s(t) = A^{-1}x(t) = P x(t)&amp;lt;/math&amp;gt;&lt;br /&gt;
Macierz kowariancji dla sygnałów &amp;lt;math&amp;gt;x(t)&amp;lt;/math&amp;gt; estymujemy tak:&lt;br /&gt;
:&amp;lt;math&amp;gt; C_x = E[x(t)x(t)^T]&amp;lt;/math&amp;gt;&lt;br /&gt;
Podstawiając (*) mamy:&lt;br /&gt;
:&amp;lt;math&amp;gt; C_x = E[x x^T] = E[As(As)^T] = A E[s s^T] A^T = A C_s A^T&amp;lt;/math&amp;gt;&lt;br /&gt;
Z założenia, że źródła są niezależne wynika, że macierz &amp;lt;math&amp;gt;C_s&amp;lt;/math&amp;gt; jest diagonalna.&lt;br /&gt;
Przekształcając powyższe równanie możemy zapisać:&lt;br /&gt;
:&amp;lt;math&amp;gt;A^{-1} C_x (A^T)^{-1} = P C_x P^T = C_s&amp;lt;/math&amp;gt;&lt;br /&gt;
Odwzorowanie &amp;lt;math&amp;gt;P = A^{-1}&amp;lt;/math&amp;gt; diagonalizuje macierz &amp;lt;math&amp;gt;C_x&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Powyższe rozumowanie jest słuszne w przypadku gdy mamy do czynienia z sygnałem stacjonarnym, tzn. jego macierz kowariancji jest niezależna od czasu, czyli przez cały czas aktywna jest ta sama konfiguracja źródeł niezależnych.&lt;br /&gt;
W przypadku gdy tak nie jest to konstrukcję filtra przestrzennego można oprzeć o  jednoczesną diagonalizację macierzy kowariancji odpowiadających różnym stanom osoby badanej.&lt;br /&gt;
&lt;br /&gt;
[[Plik:Diagonalizacja.png|200px|center]]&lt;br /&gt;
&lt;br /&gt;
==Common Spatial Pattern ==&lt;br /&gt;
===Koncepcja===&lt;br /&gt;
Dla ustalenia uwagi możemy myśleć o eksperymencie wywołującym potencjał P300. Mamy w nim dwie sytuacje eksperymentalne. Oznaczmy (&amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - target) próby, w których pojawił się oczekiwany bodziec, zaś  (&amp;lt;math&amp;gt;NT&amp;lt;/math&amp;gt; - non-target) gdy pojawił się bodziec standardowy.&lt;br /&gt;
Chcielibyśmy znaleźć taki montaż, czyli taką kombinację liniową kanałów, które maksymalizuje stosunek mocy (wariancji) sygnałów rejestrowanych w dwóch rożnych warunkach eksperymentalnych. &lt;br /&gt;
&lt;br /&gt;
===Formalizm===&lt;br /&gt;
Metoda ta polega na znalezieniu takiego kierunku &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; w przestrzeni sygnałów, że sygnał z warunku &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; rzutowany na ten kierunek ma dużą wariancje a sygnał z warunku &amp;lt;math&amp;gt;NT&amp;lt;/math&amp;gt; ma wariancję małą. &lt;br /&gt;
&lt;br /&gt;
Rzutowanie sygnału &amp;lt;math&amp;gt;x(t)&amp;lt;/math&amp;gt; na kierunek &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; odbywa się przez policzenie iloczynu skalarnego dla każdej chwili czasu &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt; s_w(t) = w^T x(t)&amp;lt;/math&amp;gt;&lt;br /&gt;
Wariancja tego rzutowanego sygnału to:&lt;br /&gt;
:&amp;lt;math&amp;gt; \mathrm{var}(s_w) = E[s_w s_w^T] = E[ w^T x (w^T x)^T] = w^T E[x x^T] w = w^T C_x w &amp;lt;/math&amp;gt;&lt;br /&gt;
Zatem znalezienie właściwego kierunku rzutowania można wyrazić jako szukanie maksimum wyrażenia &amp;lt;math&amp;gt; J(w) &amp;lt;/math&amp;gt;(jest to tzw. iloraz Rayleigh'a):&lt;br /&gt;
: &amp;lt;math&amp;gt;J(w) = \frac{w^T C_T w}{w^T C_{NT} w}  &amp;lt;/math&amp;gt;&lt;br /&gt;
Ekstremum tego ilorazu można znaleźć poprzez policzenie gradientu &amp;lt;math&amp;gt;J(w)&amp;lt;/math&amp;gt; i przyrównanie go do zera:&lt;br /&gt;
:&amp;lt;math&amp;gt; \nabla J(w) =  \frac{ 1  C_{T} w+w^T C_{T} 1}{w^T C_{NT} w}-\frac{w^T  C_{T} w\left( 1  C_{NT} w+w^T C_{NT} 1\right)}{\left(w^T  C_{NT} w\right)^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
ponieważ macierze kowariancji są symetryczne &lt;br /&gt;
::&amp;lt;math&amp;gt;\nabla J(w) =   \frac{   1}{w^T  C_{NT} w}\left[    C_{T} w+ C_{T}w  -\frac{w^T  C_{T} w}{w^T  C_{NT} w} \left(   C_{NT} w+ C_{NT}w \right) \right]&amp;lt;/math&amp;gt;&lt;br /&gt;
::&amp;lt;math&amp;gt;= \frac{   2}{w^T  C_{NT} w}\left[     C_{T}w  -\frac{w^T  C_{T} w}{w^T  C_{NT} w}   C_{NT} w \right]&amp;lt;/math&amp;gt;&lt;br /&gt;
Przyrównując to wyrażenie do zera dostajemy:&lt;br /&gt;
:&amp;lt;math&amp;gt;       C_{T}w  =\frac{w^T  C_{T} w}{w^T  C_{NT} w}   C_{NT} w   &amp;lt;/math&amp;gt;&lt;br /&gt;
Liczba &amp;lt;math&amp;gt; \lambda =    \frac{w^T  C_{T} w}{w^T  C_{NT} w}   C_{NT} w &amp;lt;/math&amp;gt; jest uogólnioną wartością własną, zaś &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; jest uogólnionym wektorem własnym odpowiadającym tej wartości. &lt;br /&gt;
&lt;br /&gt;
Aby znaleźć &amp;lt;math&amp;gt; \lambda&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; wystarczy rozwiązać zagadnienie własne. W matlabie możemy w tym celu wykorzystać funkcję &amp;lt;tt&amp;gt;eig&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Odwzorowanie to można przedstawić w postaci macierzy &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;, której każdy wiersz zawiera wagi dla odpowiednich kanałów. &lt;br /&gt;
Macierz zawierająca sygnał &amp;lt;math&amp;gt;X^{\pm}(t)&amp;lt;/math&amp;gt; &lt;br /&gt;
ma wymiary &amp;lt;math&amp;gt;C \times  N&amp;lt;/math&amp;gt;, gdzie &lt;br /&gt;
&amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; to liczba kanałów EEG, natomiast &lt;br /&gt;
&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; to liczba próbek dla każdego z kanałów. &lt;br /&gt;
Macierz &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; przekształca sygnał &amp;lt;math&amp;gt;X^{\pm}(t)&amp;lt;/math&amp;gt;  zgodnie ze wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;X^{\pm}_{CSP}(t)=P^T  X^{\pm}(t) &amp;lt;/math&amp;gt;&lt;br /&gt;
Załóżmy dalej, że sygnały &amp;lt;math&amp;gt;X^{+}_{CSP} (t)&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;X^{-}_{CSP} (t)&amp;lt;/math&amp;gt; są generowane przez niezależne procesy stochastyczne, tzn. spełnione są następujące warunki. &lt;br /&gt;
# Syganły &amp;lt;math&amp;gt;X^{+}_{CSP} (t)&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;X^{-}_{CSP} (t)&amp;lt;/math&amp;gt; są niezależne.&lt;br /&gt;
# Brak korelacji pomiędzy kanałami w sygnałach&amp;lt;math&amp;gt;X^{+}_{CSP} (t)&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;X^{-}_{CSP} (t)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Przynajmniej dla jednego z kanałów wariancja przetransformowanego sygnału jest maksymalna przy wystąpieniu bodźca i minimalna przy jego braku.&lt;br /&gt;
Po przemnożeniu równania 2.3 przez &amp;lt;math&amp;gt;(X^{\pm}_{CSP} (t))^T&amp;lt;/math&amp;gt; otrzymamy macierz kowariancji przetransformowanych sygnałów uśrednioną po realizacjach:&lt;br /&gt;
:&amp;lt;math&amp;gt;R^{\pm}_{CSP} (t) = X^{\pm}_{CSP} (t)(X^{\pm}_{CSP} (t))^T = P^T X^{\pm} (t) (X^{\pm}(t))^T P = P^T R^{\pm}P&amp;lt;/math&amp;gt;  (2.4)&lt;br /&gt;
Gdzie &amp;lt;math&amp;gt;R^{\pm}&amp;lt;/math&amp;gt; to macierz kowariancji sygnału uśredniona po realizacjach. Z warunków 1 i 2 wynika, że macierze &amp;lt;math&amp;gt;R^{+}_{CSP}&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;R^{-}_{CSP}&amp;lt;/math&amp;gt; muszą być diagonalne, natomiast z warunku 3, że ich suma daje macierz jednostkową:&lt;br /&gt;
:&amp;lt;math&amp;gt;R^{+}_{CSP} + R^{-}_{CSP} = 1 &amp;lt;/math&amp;gt;  (2.5)&lt;br /&gt;
Tak więc suma par diagonalnych wartości (&amp;lt;math&amp;gt;k^{+}_{i}&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;k^{-}_{i}&amp;lt;/math&amp;gt;) w macierzach &amp;lt;math&amp;gt;R^{+}_{CSP}&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;R^{-}_{CSP}&amp;lt;/math&amp;gt; musi być równa 1.&lt;br /&gt;
Korzystając z równania 2.5 wartości na diagonali można również zapisać za pomocą wzoru:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;k^{+}_{i} = \vec{p}^{T}_{i} R^{+} \vec{p}_{i}    &amp;lt;/math&amp;gt; (2.6)&lt;br /&gt;
:&amp;lt;math&amp;gt;k^{-}_{i} = \vec{p}^T_{i} R^{-}\vec{p}_{i} &amp;lt;/math&amp;gt; (2.7)&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;\vec{p}_{i}&amp;lt;/math&amp;gt; to kolumnowy wektor macierzy &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Po przekształceniach ilorazu równań 2.6 i 2.7 można&lt;br /&gt;
otrzymać równanie:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;R^{+} \vec{p}_{i} = \frac{k^{+}_{i}}{k^{-}_{i}} R^{-} \vec{p}_{i} &amp;lt;/math&amp;gt;  (2.8)&lt;br /&gt;
￼&lt;br /&gt;
Równanie to przedstawia ogólną formę zagadnienia wartości własnych. Takie przedstawienie problemu umożliwia zastosowanie do jego rozwiązania wydajnych metod algebraicznych.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wektor własny &amp;lt;math&amp;gt;\vec{p}_i&amp;lt;/math&amp;gt; jest interpretowany jako filtr przestrzenny. Dzięki transformacie &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; sygnał zostaje przeniesiony do przestrzeni, dla której różnica wariancji dla poszczególnych klas jest największa. Zgodnie z równaniem 2.5 najbardziej różniące się od siebie kanały są skorelowane z największą wartością własną &amp;lt;math&amp;gt;k^{+}&amp;lt;/math&amp;gt;.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie symulacyjne ===&lt;br /&gt;
&amp;lt;source lang  = matlab&amp;gt;&lt;br /&gt;
% symulowany eksperyment składa się z sinusoidy udającej alfę spoczynkową i&lt;br /&gt;
% funkcji Gaussa udającego potencjał wywołany&lt;br /&gt;
% źródła te są symulowane niezależnie a potem mieszane przez macierz L&lt;br /&gt;
% symulujemy źródła&lt;br /&gt;
% s1 - symuluje alfę&lt;br /&gt;
% s2 - symuluje &amp;quot;potencjał wywołany&amp;quot; (ERP)&lt;br /&gt;
&lt;br /&gt;
%ustawiamy parametry do symulacji sygnałów&lt;br /&gt;
Fs = 100;&lt;br /&gt;
T = 1;&lt;br /&gt;
t = 0:1/Fs:T-1/Fs;&lt;br /&gt;
N_rep = 100;&lt;br /&gt;
N_chan = 2;&lt;br /&gt;
s = zeros(N_rep,N_chan, length(t));&lt;br /&gt;
X = zeros(N_rep,N_chan, length(t));&lt;br /&gt;
&lt;br /&gt;
% filtr przestrzenny - z takimi wagami trzeba wziąść kanały EEG aby odzyskać sygnały źródłowe&lt;br /&gt;
P = [1 2&lt;br /&gt;
    1.5 1.3]; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% topografie - z takimi wagami źródła dokładają się do poszczególnych elektrod&lt;br /&gt;
A = P^(-1); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
for r =1:N_rep % tworzymy kolejne realizacje &amp;quot;eksperymentu&amp;quot;&lt;br /&gt;
    s1 = sin(2*pi*11*t +pi/2+ 0*2*pi*rand())+ 0.02*randn(size(t));  % źródło alfa&lt;br /&gt;
    s2 = exp(-((t-0.8)/0.05).^2)+ 0.01*randn(size(t));              % źródło ERP&lt;br /&gt;
       &lt;br /&gt;
    s(r,1,:) = s1;&lt;br /&gt;
    s(r,2,:) = s2;&lt;br /&gt;
    tmp = squeeze(s(r,:,:));&lt;br /&gt;
    n = 0*randn(size(tmp));&lt;br /&gt;
    X(r,:,:) = A*tmp +n; % rzutujemy sygnały źródłowe na elektrody s -&amp;gt; x&lt;br /&gt;
    &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% wycinamy warunki &lt;br /&gt;
% baseline_ind   to indeksy pierwszej połowy każdego powtórzenia &amp;quot;baseline&amp;quot;&lt;br /&gt;
% ERP_ind        to indeksy drugiej połowy każdego powtórzenia zawierająca &amp;quot;ERP&amp;quot;&lt;br /&gt;
baseline_ind = find(t&amp;lt;0.5);&lt;br /&gt;
ERP_ind = find(t&amp;gt;=0.5);&lt;br /&gt;
&lt;br /&gt;
x_baseline_kan_1 = X(:,1,baseline_ind);&lt;br /&gt;
x_baseline_kan_2 = X(:,2,baseline_ind);&lt;br /&gt;
&lt;br /&gt;
x_ERP_kan_1 = X(:,1,ERP_ind);&lt;br /&gt;
x_ERP_kan_2 = X(:,2,ERP_ind);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% liczymy średnie macierze kowariancji:&lt;br /&gt;
R_E = zeros(N_chan,N_chan);&lt;br /&gt;
R_B = zeros(N_chan,N_chan);&lt;br /&gt;
for r =1:N_rep&lt;br /&gt;
    B = squeeze(X(r,:,baseline_ind)); &lt;br /&gt;
    R_B = R_B + B*B' ;&lt;br /&gt;
    &lt;br /&gt;
    E = squeeze(X(r,:,ERP_ind));&lt;br /&gt;
    R_E = R_E + E*E' ;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
R_B = R_B/N_rep;&lt;br /&gt;
R_E = R_E/N_rep;&lt;br /&gt;
&lt;br /&gt;
% rozwiązujemy uogólnione zagadnienie własne&lt;br /&gt;
[W,Lambda]=eig(R_E,R_B); % możliwa jest też optymalizacja wzg. średniej macierzy kowariancji (R_B+R_A)/2);&lt;br /&gt;
&lt;br /&gt;
% odzyskujemy sygnały źródeł&lt;br /&gt;
for r =1:N_rep&lt;br /&gt;
    S(r,:,:) = W'*squeeze(X(r,:,:));&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% pobieramy wycinki odpowiadające obu częściom eksperymentu z estymowanych&lt;br /&gt;
% źródeł&lt;br /&gt;
s_baseline_estymowany_kan1 = squeeze(  S(:,1,baseline_ind));&lt;br /&gt;
s_baseline_estymowany_kan2 = squeeze(  S(:,2,baseline_ind));&lt;br /&gt;
&lt;br /&gt;
s_ERP_estymowany_kan1 = squeeze(S(:,1,ERP_ind));&lt;br /&gt;
s_ERP_estymowany_kan2 = squeeze(S(:,2,ERP_ind));&lt;br /&gt;
&lt;br /&gt;
%%%%%%%%%%%%%% Ilustracje %%%%%%%%%%%%%%%%%%%%%%%&lt;br /&gt;
% ilustracja sygnałów mierzonych&lt;br /&gt;
figure(1);clf&lt;br /&gt;
subplot(2,2,1);&lt;br /&gt;
    plot(t(baseline_ind),(squeeze(X(:,1,baseline_ind)))','b'); hold on&lt;br /&gt;
    plot(t(ERP_ind),(squeeze(  X(:,1,ERP_ind)))','r'); hold off&lt;br /&gt;
    xlabel('elektroda 1')&lt;br /&gt;
    title('ilustracja sytuacji pomiarowej -\newline znane są potencjały na elektrodach w dwóch warunkach eksperymentalnych')&lt;br /&gt;
subplot(2,2,3);&lt;br /&gt;
    plot(t(baseline_ind),(squeeze(X(:,1,baseline_ind)))','b'); hold on&lt;br /&gt;
    plot(t(ERP_ind),(squeeze(  X(:,2,ERP_ind)))','r'); hold off&lt;br /&gt;
    xlabel('elektroda 2')&lt;br /&gt;
subplot(1,2,2)&lt;br /&gt;
    plot(x_baseline_kan_1(:),x_baseline_kan_2(:),'b.');&lt;br /&gt;
    hold on&lt;br /&gt;
    plot(x_ERP_kan_1(:),x_ERP_kan_2(:),'r.');&lt;br /&gt;
    xlim([-2,2])&lt;br /&gt;
    ylim([-2,2])&lt;br /&gt;
    axis equal&lt;br /&gt;
    &lt;br /&gt;
    % wektor własny odpowiadający największej wartości własnej jest&lt;br /&gt;
    % kierunkiem najbardziej różnicującym warunki eksperymentalne&lt;br /&gt;
    disp('wartości własne znajdują się na przekątnej macierzy Lambda')&lt;br /&gt;
    disp(Lambda)&lt;br /&gt;
    % rysujemy wersory jednostkowe w kierunkach wektorów własnych&lt;br /&gt;
    w1 = W(:,1); &lt;br /&gt;
    w1 = w1/norm(w1);&lt;br /&gt;
    w2 = W(:,2); &lt;br /&gt;
    w2 = w2/norm(w2);&lt;br /&gt;
    line([0, w1(1) ],[0,w1(2)],'Color',[0,0.3,0])&lt;br /&gt;
    text(w1(1),w1(2),'wektor własny 1')&lt;br /&gt;
    line([0, w2(1) ],[0,w2(2)],'Color',[1,0,1])&lt;br /&gt;
    text(w2(1),w2(2),'wektor własny 2')&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    xlabel('Amplituda na elektrodzie 1')&lt;br /&gt;
    ylabel('Amplituda na elektrodzie 2')   &lt;br /&gt;
    legend('baseline','ERP')&lt;br /&gt;
&lt;br /&gt;
% Ilustracja estymowanych źródeł&lt;br /&gt;
figure(2);clf&lt;br /&gt;
subplot(2,2,1);&lt;br /&gt;
    plot(t(baseline_ind),(squeeze(S(:,1,baseline_ind)))','b');hold on&lt;br /&gt;
    plot(t(ERP_ind),(squeeze(S(:,1,ERP_ind)))','r');hold off&lt;br /&gt;
    xlabel('estymowane zrodlo  1')&lt;br /&gt;
    title('ilustracja estymacji -\newline estymowane są potencjały źródeł w dwóch warunkach eksperymentalnych')    &lt;br /&gt;
subplot(2,2,3);&lt;br /&gt;
    plot(t(baseline_ind),(squeeze(S(:,2,baseline_ind)))','b');hold on&lt;br /&gt;
    plot(t(ERP_ind),(squeeze(S(:,2,ERP_ind)))','r');hold off&lt;br /&gt;
    xlabel('estymowane zrodlo  2');&lt;br /&gt;
subplot(1,2,2)&lt;br /&gt;
    plot(s_baseline_estymowany_kan1(:),s_baseline_estymowany_kan2(:),'b.');&lt;br /&gt;
    hold on&lt;br /&gt;
    plot(s_ERP_estymowany_kan1(:),s_ERP_estymowany_kan2(:),'r.');   &lt;br /&gt;
    &lt;br /&gt;
    xlabel('Amplituda estym. źródła 1')&lt;br /&gt;
    ylabel('Amplituda estym. źródła 2')   &lt;br /&gt;
    legend('baseline','ERP')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zastosowanie filtra CSP do detekcji potencjału P300==&lt;br /&gt;
===Eksperyment===&lt;br /&gt;
====Przygotowanie do badania:====&lt;br /&gt;
* założyć czepek z elektrodami w systemie 10-20;&lt;br /&gt;
* elektrody referencyjne: M1 i M2;&lt;br /&gt;
* elektroda GND w pozycji AFz.&lt;br /&gt;
&lt;br /&gt;
====Przygotowanie scenariuszy obci ====&lt;br /&gt;
* w terminalu uruchomić &amp;lt;tt&amp;gt;obci srv&amp;lt;/tt&amp;gt;;&lt;br /&gt;
* w terminalu uruchomić &amp;lt;tt&amp;gt;obci_gui --preset brain2013&amp;lt;/tt&amp;gt;;&lt;br /&gt;
* w interfejsie GUI zapisujemy scenariusze do własnego katalogu np &amp;amp;bdquo;P300&amp;amp;rdquo;&lt;br /&gt;
** &amp;amp;bdquo;P-Brain2013 Signal (with ID)&amp;amp;rdquo; jako np. &amp;amp;bdquo;Sygnal&amp;amp;rdquo;&lt;br /&gt;
** &amp;amp;bdquo;P-Brain2013 Calibration p300&amp;amp;rdquo; jako &amp;amp;bdquo;kalibracjaP300&amp;amp;rdquo;&lt;br /&gt;
** &amp;amp;bdquo;P-Brain 2013 p300&amp;amp;rdquo; jako &amp;amp;bdquo;Labirynt&amp;amp;rdquo;&lt;br /&gt;
* w przeglądarce plików otwórz katalog ~/.obci/scenarios/P300. Powinien on zawierać pliki: Sygnal.ini, kalibracjaP300.ini, Labirynt.ini oraz katalogi  Sygnal_configs, kalibracjaP300_configs, Labirynt_configs.&lt;br /&gt;
*  edytujemy parametry peerów.&lt;br /&gt;
** z katalogu ~/.obci/scenarios/P300/Sygnal_configs kopiujemy plik amplifier.ini do katalogu ~/.obci/scenarios/P300 jako global_amplifier.ini. To pozwoli nam zmieniać ustawienia wzmacniacza dla wszystkich scenariuszy jednocześnie.&lt;br /&gt;
** w naszych scenariuszach zapisanych w plikach Sygnal.ini, kalibracjaP300.ini, Labirynt.ini podmieniamy ścieżkę &amp;lt;tt&amp;gt;config =&amp;lt;/tt&amp;gt; w sekcji &amp;lt;tt&amp;gt;[peers.amplifier]&amp;lt;/tt&amp;gt; tak, aby pokazywała na ten skopiowany plik global_amplifier.ini&lt;br /&gt;
** w tym pliku global_amplifier.ini podmieniamy linijki (tak aby były to listy faktycznie wykorzystywanych kanałów) z:&lt;br /&gt;
*** &amp;lt;tt&amp;gt;active_channels&amp;lt;/tt&amp;gt;&lt;br /&gt;
*** &amp;lt;tt&amp;gt;channel_names&amp;lt;/tt&amp;gt;&lt;br /&gt;
** dodajemy też linijkę: &amp;lt;tt&amp;gt;sampling_rate = 256&amp;lt;/tt&amp;gt;&lt;br /&gt;
* wchodzimy po kolei do katalogów: Sygnal_configs, kalibracjaP300_configs, Labirynt_configs i odnajdujemy plik switch_backup.ini. W tym pliku ustawiamy parametr &amp;lt;tt&amp;gt;new_scenario&amp;lt;/tt&amp;gt; na pusty. To spowoduje, że scenariusze te nie będą uruchamiać kolejnych scenariuszy po zakończeniu działania.&lt;br /&gt;
** edytujemy plik ~/.obci/scenarios/P300/kalibracjaP300_configs/clasifier.ini &lt;br /&gt;
*** zmieniamy linię&lt;br /&gt;
::: &amp;lt;tt&amp;gt;ignore_channels = DriverSaw;AmpSaw;PO7;PO8&amp;lt;/tt&amp;gt;&lt;br /&gt;
::: na &lt;br /&gt;
::: &amp;lt;tt&amp;gt;ignore_channels = DriverSaw;AmpSaw;A1;A2&amp;lt;/tt&amp;gt;&lt;br /&gt;
::* oraz linię:&lt;br /&gt;
::: &amp;lt;tt&amp;gt;montage_channels = PO7;PO8&amp;lt;/tt&amp;gt;&lt;br /&gt;
::: na &lt;br /&gt;
::: &amp;lt;tt&amp;gt;montage_channels = A1;A2&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Przeprowadzenie badania:====&lt;br /&gt;
# Uruchom scenariusz &amp;amp;bdquo;Sygnał&amp;amp;rdquo;.&lt;br /&gt;
# Tworzy on w katalogu domowym plik o nazwie &amp;lt;tt&amp;gt;file_id_name&amp;lt;/tt&amp;gt;.&lt;br /&gt;
# Uruchamiamy Svaroga z terminala poleceniem &amp;lt;tt&amp;gt;svarog&amp;lt;/tt&amp;gt;. W zakładce sygnały on-line odnajdujemy nazwę naszego scenariusza &amp;amp;bdquo;Sygnal&amp;amp;rdquo;. Podłączamy się do niego i poprawiamy ewentualnie źle kontaktujące elektrody.&lt;br /&gt;
# Jak już jesteśmy zadowoleni z jakości sygnału to zatrzymujemy scenariusz &amp;amp;bdquo;Sygnal&amp;amp;rdquo; w obci.&lt;br /&gt;
# W pliku &amp;lt;tt&amp;gt;file_id_name&amp;lt;/tt&amp;gt;  znajduje się string, który stanowi rdzeń do tworzenia nazw plików, z których korzystają nasze scenariusze. Proszę zmienić ten string np. na: &amp;lt;tt&amp;gt;test1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
# Uruchamiamy scenariusz &amp;amp;bdquo;kalibracjaP300&amp;amp;rdquo;. Badany będzie oglądał interfejs z trzema literami A B C migającymi w losowej kolejności. Zadaniem jest zliczanie mignięć litery B.&lt;br /&gt;
# Po zakończeniu kalibracji uruchamiamy scenariusz &amp;amp;bdquo;Labirynt&amp;amp;rdquo;.&lt;br /&gt;
# Danych z kalibracji potrzebować będziemy kilka zestawów.  Proszę powtórzyć kilkukrotnie scenariusz &amp;amp;bdquo;kalibracjaP300&amp;amp;rdquo;. Przed każdym uruchomieniem trzeba zmienić string w pliku &amp;lt;tt&amp;gt;file_id_name&amp;lt;/tt&amp;gt; np. na &amp;lt;tt&amp;gt;test???&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;???&amp;lt;/tt&amp;gt; oznacza kolejne numery.&lt;br /&gt;
&lt;br /&gt;
===Analiza wstępna===&lt;br /&gt;
* Wczytać dane kalibracyjne do Matlaba i pociąć je na realizacje typu T &amp;amp;mdash; &amp;amp;bdquo;target&amp;amp;rdquo; (związane z wystąpieniami litery &amp;amp;bdquo;B&amp;amp;rdquo;) i NT &amp;amp;mdash; &amp;amp;bdquo;non-target&amp;amp;rdquo; (pozostałe litery) o długości &amp;amp;minus;200 do +800 ms wokół triggerów. Dla każdej realizacji odjąć trend liniowy.&lt;br /&gt;
* Sygnał zmontować wzgl. &amp;amp;bdquo;połączonych uszu&amp;amp;rdquo; i wyświetlić średnie przebiegi dla warunku T i NT w układzie topograficznym &amp;amp;mdash; wykorzystać w tym celu funkcję &amp;lt;tt&amp;gt;topoplot&amp;lt;/tt&amp;gt; z pakietu Eeglab.&lt;br /&gt;
&lt;br /&gt;
Poniżej zaprezentowany jest przykładowy skrypt do cięcia danych wokół znaczników. Działa on z plikami zawartymi w archiwum:&lt;br /&gt;
: [[Plik:KalibracjaP300.tar.gz]] &lt;br /&gt;
Korzysta z funkcji pomocniczych dostępnych w dystrybucji obci w katalogu &lt;br /&gt;
: /usr/share/openbci/analysis/matlab_obci_signal_processing&lt;br /&gt;
Openbci można pobrać z https://github.com/BrainTech/openbci&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = matlab&amp;gt;&lt;br /&gt;
% ustalamy nzawy plików z danymi&lt;br /&gt;
nazwaPliku = 'p_6301423_calibration_p300.obci';&lt;br /&gt;
nameOfXMLFile = strcat(nazwaPliku,'.xml');&lt;br /&gt;
nameOfTagFile = strcat(nazwaPliku,'.tag'); %tagi = znaczniki zdarzeń&lt;br /&gt;
namesOfDataFiles = strcat(nazwaPliku,'.raw');&lt;br /&gt;
&lt;br /&gt;
% inicjujemy obiekt rm&lt;br /&gt;
rm = ReadManager(nameOfXMLFile,namesOfDataFiles,nameOfTagFile);&lt;br /&gt;
&lt;br /&gt;
% obieramy przydatne parametry i znaczniki&lt;br /&gt;
numberOfChannels  = rm.get_param('number_of_channels');&lt;br /&gt;
namesOfChannels   = rm.get_param('channels_names');&lt;br /&gt;
samplingFrequency = rm.get_param('sampling_frequency');&lt;br /&gt;
tagsStruct        = rm.get_tags();&lt;br /&gt;
&lt;br /&gt;
% tworzenie list znaczników Target i NonTarget&lt;br /&gt;
numberOfStruct = length(tagsStruct);&lt;br /&gt;
targetTimeStamps = [];&lt;br /&gt;
NonTargetTimeStamps = [];&lt;br /&gt;
for structNumber = 1:numberOfStruct % iterujemy się przez tagi&lt;br /&gt;
    if(strcmp(tagsStruct(structNumber).name,'blink')) % szukamy tagów o nazwie 'blink'&lt;br /&gt;
        index = tagsStruct(structNumber).children.index; % tu jest numer pola stymulacji&lt;br /&gt;
        target= tagsStruct(structNumber).children.target;% tu jest numer pola na którym wyświetlany jest target&lt;br /&gt;
        if index == target % warunek na to, że mamy do czynienia z tagiem target&lt;br /&gt;
            targetTimeStamps = [targetTimeStamps tagsStruct(structNumber).start_timestamp]; %dodajemy timeStamp do listy targetów&lt;br /&gt;
        else&lt;br /&gt;
            NonTargetTimeStamps = [NonTargetTimeStamps tagsStruct(structNumber).start_timestamp];%dodajemy timeStamp do listy non-targetów&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% pobieramy próbki&lt;br /&gt;
samples = double(rm.get_samples()); % konwersja na double jest potrzebna żeby dobrze funkcjonowało filtrowanie&lt;br /&gt;
samples=samples(1:8,:); % odrzucamy kanały, które nie mają EEG&lt;br /&gt;
numberOfChannels =8;&lt;br /&gt;
&lt;br /&gt;
% filtrujemy dolnoprzepustowo aby odrzucić artefakty sieci i część&lt;br /&gt;
% artefaktów mięśniowych&lt;br /&gt;
[b,a] = cheby2(6,80,25 /(samplingFrequency/2),'low');&lt;br /&gt;
for ch = 1:numberOfChannels&lt;br /&gt;
    samples(ch,:)=filtfilt(b,a,samples(ch,:));&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% montujemy dane do wspólnej średniej (common average)&lt;br /&gt;
M = -ones(8,8)/8;&lt;br /&gt;
M=M+eye(8,8)*9/8;&lt;br /&gt;
samples = 0.0715*M*samples;&lt;br /&gt;
&lt;br /&gt;
% wycinamy dane wokół znaczników&lt;br /&gt;
PRE = -0.2; % czas przed tagiem w sek.&lt;br /&gt;
POST = 0.8; % czas po tagu w sek.&lt;br /&gt;
wycinek = floor(PRE*samplingFrequency:POST*samplingFrequency); % tablica ze &amp;quot;standardowymi&amp;quot; indeksami do cięcia&lt;br /&gt;
&lt;br /&gt;
% pobieramy targety&lt;br /&gt;
TargetSignal = zeros(length(targetTimeStamps),numberOfChannels, length(wycinek)); % tablica na sygnały target&lt;br /&gt;
for trialNumber = 1:length(targetTimeStamps)&lt;br /&gt;
    trigerOnset = floor(targetTimeStamps(trialNumber)*samplingFrequency);&lt;br /&gt;
    tenWycinek = wycinek + trigerOnset;&lt;br /&gt;
    if tenWycinek(1)&amp;gt;0 &amp;amp;&amp;amp; tenWycinek(end)&amp;lt;=size(samples,2) % test czy wycinek który chcemy pobrać nie wystaje poza dostępny sygnał&lt;br /&gt;
        tmpSignal = samples(:,tenWycinek);&lt;br /&gt;
        tmpSignal = detrend(tmpSignal')'; % usuwanie liniowego trendu - przy krótkich wycinkach działa lepiej niż filtrowanie górnoprzepustowe&lt;br /&gt;
        TargetSignal(trialNumber, :,:) = tmpSignal;&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% pobieramy non-targety&lt;br /&gt;
NonTargetSignal = zeros(length(NonTargetTimeStamps),numberOfChannels, length(wycinek));% tablica na sygnały non-target&lt;br /&gt;
for trialNumber = 1:length(NonTargetTimeStamps)&lt;br /&gt;
    trigerOnset = floor(NonTargetTimeStamps(trialNumber)*samplingFrequency);&lt;br /&gt;
    tenWycinek = wycinek + trigerOnset;&lt;br /&gt;
    if tenWycinek(1)&amp;gt;0 &amp;amp;&amp;amp; tenWycinek(end)&amp;lt;=size(samples,2)&lt;br /&gt;
        tmpSignal = samples(:,tenWycinek);&lt;br /&gt;
        tmpSignal = detrend(tmpSignal')';&lt;br /&gt;
        NonTargetSignal(trialNumber, :,:) = tmpSignal;&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
%&lt;br /&gt;
% dla ilustracji podglądamy średnie po powtórzeniach ze wszystkich targetów&lt;br /&gt;
% i non-targetów&lt;br /&gt;
plot(squeeze(mean(TargetSignal,1))','r');&lt;br /&gt;
hold on&lt;br /&gt;
plot(squeeze(mean(NonTargetSignal,1))','b')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Analiza CSP===&lt;br /&gt;
* Korzystając z danych kalibracyjnych wykonać analizę CSP wzmacniającą potencjał P300.&lt;br /&gt;
* Zaprezentować średnią ze wszystkich kanałów źródłowych z warunku target (jeden kolor) i non-target (inny kolor) w subplotach ułożonych w prostokątnej siatce. Zaobserwować dla którego kanału średnie różnią się najbardziej. Czy jest związek tego kanału z wartościami własnymi?&lt;br /&gt;
&lt;br /&gt;
* Dla kanału najbardziej różnicującego wykonać mapki topograficzne wektorów odpowiadających:&lt;br /&gt;
** filtrowi przestrzennemu &lt;br /&gt;
** rzutu topograficznego źródła na elektrody.&lt;br /&gt;
* Do wykonania tych mapek wykorzystać funkcję &amp;lt;tt&amp;gt;topoplot&amp;lt;/tt&amp;gt; z pakietu &amp;lt;tt&amp;gt;eeglab&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Zbadać powtarzalność topografii pomiędzy plikami konfiguracyjnymi.&lt;br /&gt;
&lt;br /&gt;
===Wybór i separacja cech===&lt;br /&gt;
* Przedstaw na rysunkach nałożone na siebie pojedyncze realizacje z warunków target i non-target po rzutowaniu na wektor &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; odpowiadający największej i kolejnej wartości  własnej. &lt;br /&gt;
* Przedstaw wykresy punktowe, takie że na jednej osi jest moc sygnału odpowiadającego największej wartości własnej a na drugiej osi kolejnej wartości własnej; jeden punkt reprezentuje jedno powtórzenie.&lt;br /&gt;
* Wykonaj serię wykresów jak w poprzednim punkcie dla uśrednień kolejno po 2, 4, 6, 8 i 10 realizacjach. Zaobserwuj jak zmienia się separacja w grupach target i non-target.&lt;br /&gt;
&lt;br /&gt;
==Filtry przestrzenne dla SSEP ==&lt;br /&gt;
&lt;br /&gt;
=== Teoria===&lt;br /&gt;
Ciekawa koncepcja filtra przestrzennego dla SSVEP zaprezentowana jest  tu: http://www.eurasip.org/Proceedings/Eusipco/Eusipco2009/contents/papers/1569193209.pdf&lt;br /&gt;
&lt;br /&gt;
Po krótce można ją rozumieć podobnie do tego co robiliśmy rozważając filtry przestrzenne CSP, z tym, że dla SSVEP oraz innych potencjałów wywołanych stanu ustalonego możemy skorzystać z dodatkowych informacji dotyczących poszukiwanych źródeł. Wiemy mianowicie, że powinny one oscylować z częstością bodźca, i być może jej harmonicznych.&lt;br /&gt;
&lt;br /&gt;
Przyda nam się macierz &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; zbudowana tak, że w kolejnych kolumnach znajdują się sinusy i cosinusy kolejnych częstości harmonicznych. Wektory te unormujemy, żeby miały energię równą 1. Innymi słowy macierz &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; zbudowana jest z wersorów rozpinających przestrzeń, w której powinien znajdować się sygnał SSVEP.&lt;br /&gt;
&lt;br /&gt;
W matlabie możemy taką macierz zbudować tak:&lt;br /&gt;
&amp;lt;source lang = matlab&amp;gt;&lt;br /&gt;
% Fs - częstość próbkowania&lt;br /&gt;
% numberOfSamples - długość sygnału w próbkach&lt;br /&gt;
% numberOfHarmonics - liczba harmonicznych, które chcemy włączyć do analizy&lt;br /&gt;
t = (0:1:numberOfSamples - 1)/Fs; &lt;br /&gt;
S = zeros(numberOfSamples, 2*numberOfHarmonics);&lt;br /&gt;
&lt;br /&gt;
for harmonicNumber = 1:numberOfHarmonics&lt;br /&gt;
    c = cos(2*pi*stimulationFrequency*harmonicNumber*t);&lt;br /&gt;
    s = sin(2*pi*stimulationFrequency*harmonicNumber*t);&lt;br /&gt;
    S(:,(harmonicNumber - 1)*2 + 1) = c/norm(c);&lt;br /&gt;
    S(:,(harmonicNumber - 1)*2 + 2) = s/norm(s);&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aby w badanym sygnale znaleźć składowe odpowiadające SSVEP musimy rzutować sygnał &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; (macierz sygnałów ''kanały x próbki'')  na przestrzeń rozpiętą przez &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;A = X*S&amp;lt;/math&amp;gt;&lt;br /&gt;
Macierz &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; zawiera współczynniki będące iloczynami skalarnymi sygnałów i wersorów. Mówią one o tym &amp;quot;jak duże&amp;quot; jest sinusa bądź cosinusa o danej częstości w pierwotnym sygnale. Komponenty SSVEP zawarte w sygnale &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; odzyskujemy tak:&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathrm{SSVEP} = A S^T&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Modelujemy rejestrowany sygnał jako:&lt;br /&gt;
:&amp;lt;math&amp;gt;X = \mathrm{SSVEP} + Y &amp;lt;/math&amp;gt;&lt;br /&gt;
gdzie: &lt;br /&gt;
:&amp;lt;math&amp;gt;Y = X-\mathrm{SSVEP}&amp;lt;/math&amp;gt; &lt;br /&gt;
: to wszystkie komponenty sygnału, które nas nie interesują.&lt;br /&gt;
&lt;br /&gt;
Filtr przestrzenny, który chcemy zbudować powinien maksymalizować stosunek wariancji &amp;lt;math&amp;gt;\mathrm{SSVEP} = A S^T&amp;lt;/math&amp;gt; do wariancji &amp;lt;math&amp;gt;Y = X-\mathrm{SSVEP}&amp;lt;/math&amp;gt;. Macierz kowariancji powinna być uśredniona po powtórzeniach a kowariancja sygnału w każdym powtórzeniu powinna być znormalizowana poprzez podzielenie przez jej ślad (Matlabowa funkcja cov() już wykonuje tę operację).&lt;br /&gt;
Dalej możemy zastosować technikę znaną z konstrukcji filtrów CSP, tzn. maksymalizacji ilorazu Rayleigh'a za pomocą rozwiązania ogólnionego zagadnienia własnego dla macierzy kowariancji &amp;lt;math&amp;gt;\mathrm{SSVEP} &amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;Y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Poniżej prosta demonstracja dla danych zebranych EEG przy stymulacji SSVEP z częstotliwością 38Hz.===&lt;br /&gt;
Spakowane dane: [[Plik:PrzykladoweDaneSSVEP.mat.gz]].&lt;br /&gt;
W oparciu o powyższy opis proszę zaimplementować  funkcję &amp;lt;tt&amp;gt;cosSinCSP&amp;lt;/tt&amp;gt;. Prawidłowo zaimplementowana funkcja wraz z poniższym kodem powinna generować rysunek:&lt;br /&gt;
[[Plik:Rys_SSVEP_demo.png|400px|thumb|right|podpis grafiki]] &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = matlab&amp;gt;&lt;br /&gt;
% wczytujemy dane&lt;br /&gt;
load('PrzykladoweDaneSSVEP.mat');&lt;br /&gt;
&lt;br /&gt;
[numberOfTrials numberOfChannels numberOfSamples] = size(X.data);&lt;br /&gt;
namesOfChannels = X.channels;&lt;br /&gt;
 &lt;br /&gt;
% numberOfChannels numberOfSamples numberOfTrials&lt;br /&gt;
W = zeros(numberOfChannels,numberOfChannels);&lt;br /&gt;
numberOfHarmonics = 3;&lt;br /&gt;
signal = X.data; % (  powtórzenie,  kanał, próbki)&lt;br /&gt;
 &lt;br /&gt;
S = zeros(size(signal));&lt;br /&gt;
W = cosSinCSP(signal,X.stimulation,numberOfHarmonics,X.sampling);&lt;br /&gt;
for powt = 1:size(signal,1)&lt;br /&gt;
    S(powt,:,:) = W'*squeeze(signal(powt,:,:));&lt;br /&gt;
end&lt;br /&gt;
 &lt;br /&gt;
figure('Name',['Stymulacja: ',num2str(X.stimulation),' Hz'])&lt;br /&gt;
for i =1:numberOfChannels&lt;br /&gt;
    % rysujemy widma uśrednione po realizacjach dla danych &lt;br /&gt;
    % z oryginalnych kanałów EEG&lt;br /&gt;
    subplot(2,8,i)&lt;br /&gt;
    PP=0;&lt;br /&gt;
    for rep = 1:numberOfTrials&lt;br /&gt;
        x = signal(rep,i,:);&lt;br /&gt;
        [Pxx,ff] = pwelch(x, X.sampling, 1, X.sampling, X.sampling);&lt;br /&gt;
        PP =PP + Pxx;&lt;br /&gt;
    end&lt;br /&gt;
    plot(ff(ff&amp;lt;60),PP(ff&amp;lt;60))&lt;br /&gt;
    title(namesOfChannels{i})&lt;br /&gt;
 &lt;br /&gt;
    % rysujemy widma uśrednione po realizacjach dla danych &lt;br /&gt;
    % z estymowanych źródeł CSP&lt;br /&gt;
    subplot(2,8,8+i)&lt;br /&gt;
    PP=0;&lt;br /&gt;
    for rep = 1:numberOfTrials&lt;br /&gt;
        s = S(rep,i,:);&lt;br /&gt;
        [Pss,ff]=pwelch(s, X.sampling, 1, X.sampling, X.sampling);&lt;br /&gt;
        PP =PP + Pss;&lt;br /&gt;
    end&lt;br /&gt;
    plot(ff(ff&amp;lt;60),PP(ff&amp;lt;60))&lt;br /&gt;
    title(['źródło CSP: ', num2str(i)])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przykładowy skrypt i dane prezentujący konstrukcję i działanie tego typu filtrów przestrzennych dla pełnych danych z eksperymentu SSVEP: [[Plik:SSVEP_demo_csp.tar.gz]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===Eksperyment ASSR===&lt;br /&gt;
W eksprymencie wykorzystujemy układ do generacji potencjałów słuchowych stanu ustalonego (ASSR). Wejście układu ASSR typu mini-jack wkładamy w wyjście słuchawkowe w laptopie. Drugie wejście układu ASSR wkładamy do wyjścia triggera we wzmacniaczu. Uruchamiamy plik dźwiękowy MM40tr.wav. Można go znalezc w: http://www.fuw.edu.pl/~suffa/LabEEG/MM40tr.wav&lt;br /&gt;
&lt;br /&gt;
Stymulacja dźwiękowa składa sie z fali nośnej o częstości 400 Hz modulowanej z częstością 40 Hz. Plik dźwiękowy zawiera 5 sekund ciszy i 5 sekund stymulacji, powtórzone 40 razy.&lt;br /&gt;
&lt;br /&gt;
====Rejestracja sygnału====&lt;br /&gt;
# Zakładamy czepek i elektrody w systemie 10-10, dbamy o to by opory pomiędzy elektrodami były poniżej 5 k&amp;amp;Omega; i różnice pomiędzy oporami różnych elektrod nie przekraczały 20%.&lt;br /&gt;
# Oklejamy kwadrat 3&amp;amp;times;3 elektrod na korze słuchowej z lewej strony (elektrody FT7, FC5, FC3, T7, C5, T3, TP7, CP5, CP3), 3&amp;amp;times;3 elektrod na korze słuchowej z prawej strony (elektrody FT8, FC6, FC4, T8, C6, T4, TP8, CP6, CP4), elektrody Fz, Cz, Pz i Oz, elektrody referencyjne A1 i A2. W sumie powinno być 24 elektrody.&lt;br /&gt;
# Elektrodę GND mocujemy na pozycji AFz.&lt;br /&gt;
# Sygnał rejestrujemy z częstością 2048 Hz.&lt;br /&gt;
# Do rejestracji stosujemy scenariusz 'ASSR' w interfejsie obci_gui.&lt;br /&gt;
&lt;br /&gt;
====Analiza====&lt;br /&gt;
 JZ: zmieniłbym analizę na czas-częstość i zrobił porównanie montażu usznego do filtra G.G. Moliny&lt;br /&gt;
&lt;br /&gt;
Początek stymulacji dźwiękowej oznaczymy jako 0. Poniższą analizę zastosuj dla sygnałów w referencji do uśrednionych odprowadzeń usznych A1 i A2.&lt;br /&gt;
Wyznaczenie pasma częstości odpowiedzi ASSR&lt;br /&gt;
# Z sygnału wycinamy fragmenty od 0 do 5 sek. dla wszystkich elektrod położone nad korą słuchową.&lt;br /&gt;
# Dla każdej realizacji obliczamy widma metodą Welcha.&lt;br /&gt;
# Otrzymane zespolone widma uśredniamy po realizacjach.&lt;br /&gt;
# Sprawdzamy czy w uśrednionym widmie występuję maksimum w częstości modulacji tj. 40 Hz.&lt;br /&gt;
&lt;br /&gt;
====Wyznaczenie przebiegu czasowego ERD i ERS====&lt;br /&gt;
# Zaprojektuj filtry pasmowo przepustowe (Czebyszewa 2 rodzaju) zgodne z wyznaczonym pasmem. Zbadaj funkcje przenoszenia i odpowiedzi impulsowej.&lt;br /&gt;
# Powycinaj sygnały od &amp;amp;minus;5 do +10 sekund (wszystkie kanały). Przefiltruj każdą realizację.&lt;br /&gt;
# Oblicz moc chwilową za pomocą transformaty Hilberta (kwadrat modułu transformaty Hilberta).&lt;br /&gt;
# Uśrednij moc chwilową po realizacjach.&lt;br /&gt;
# Oblicz względną zmianę mocy chwilowej względem czasu &amp;amp;minus;4 do &amp;amp;minus;2 s. W ten sposób otrzymasz przebieg ERD i ERS w czasie.&lt;br /&gt;
# Wykreśl ERD i ERS w układzie topograficznym. (Rozmieść subploty tak, aby z w przybliżeniu odpowiadały pozycjom elektrod).&lt;br /&gt;
&lt;br /&gt;
====Transformacja Hjortha====&lt;br /&gt;
Transformacja Hjortha jest przybliżeniem numerycznym transformacji Laplace'a, czyli drugiej pochodnej przestrzennej. Obliczamy ją jako różnicę potencjału pomiędzy daną elektrodą i średnią z czterech sąsiednich elektrod.&lt;br /&gt;
Przelicz potencjały z elektrod, w których występuję odpowiedź ASSR na montaż Hjortha i powtórz analizę ERD/ERS opisaną powyżej.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==ICA jako filtr przestrzenny==&lt;br /&gt;
===Definicja ===&lt;br /&gt;
Independent Component Analysis (ICA) jest metodą statystycznej analizy sygnałów, która dokonuje dekompozycji wielokanałowych zapisów na składowe niezależne w sensie statystycznym.&lt;br /&gt;
Dwie składowe &amp;lt;math&amp;gt;s_{1}&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;s_{2}&amp;lt;/math&amp;gt; są niezależne jeżeli wiedza o wartości &amp;lt;math&amp;gt;s_{1}&amp;lt;/math&amp;gt; nie daje żadnych informacji o możliwych wartościach &amp;lt;math&amp;gt;s_{2}&amp;lt;/math&amp;gt;. ICA może być wyrażona przez prosty model generatywny:&lt;br /&gt;
: &amp;lt;math&amp;gt; \mathbf{x} = \mathbf{D}\mathbf{s} &amp;lt;/math&amp;gt;&lt;br /&gt;
: gdzie &amp;lt;math&amp;gt;\mathbf{x}=\{x^{1},x^{2},\dots, x^{n}\}&amp;lt;/math&amp;gt; jest zmierzonym &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; kanałowym sygnałem, &amp;lt;math&amp;gt;\mathbf{D}&amp;lt;/math&amp;gt; jest macierzą mieszającą zaś &amp;lt;math&amp;gt;\mathbf{s}=\{s^{1},s^{2},\dots,s^{n} \}&amp;lt;/math&amp;gt; jest aktywnością  &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; źródeł. Podstawowym założeniem dotyczącym &amp;lt;math&amp;gt;\mathbf{s}&amp;lt;/math&amp;gt; jest to, że &amp;lt;math&amp;gt;s^{i}&amp;lt;/math&amp;gt; są statystycznie niezależne.  Aby wyestymować model musimy też założyć, że składowe mają niegaussowskie rozkłady wartości (Hyvarinen, 2000).&lt;br /&gt;
&lt;br /&gt;
Dodatkowo model ten zakłada następujące fakty:&lt;br /&gt;
# Sygnał jest liniową mieszaniną aktywności źródeł&lt;br /&gt;
# Sygnały pochodzące z każdego ze źródeł są niezależne od pozostałych&lt;br /&gt;
# Źródła oraz proces ich mieszania są stacjonarne, tzn, ich momenty statystyczne nie zależą od czasu&lt;br /&gt;
# Energie (wariancje) źródeł nie mogą być wyznaczone jednoznacznie. Dzieje się tak ponieważ pomnożenie amplitudy &amp;lt;math&amp;gt;i-{tego}&amp;lt;/math&amp;gt; źródła może być uzyskane poprzez przemnożenie albo &amp;lt;math&amp;gt;s^{i}&amp;lt;/math&amp;gt; albo przez przemnożenie  &amp;lt;math&amp;gt;i-tej&amp;lt;/math&amp;gt; kolumny macierzy &amp;lt;math&amp;gt;\mathbf{D}&amp;lt;/math&amp;gt;}.  Naturalnym rozwiązaniem tej niejednoznaczności jest wprowadzenie konwencji, że komponenty są normowane tak aby miały wariancję 1: &amp;lt;math&amp;gt;E[s^{i}]=1&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Kolejność komponentów jest dowolna.  Bo jeśli: w ten sam sposób zmienimy kolejność komponentów w &amp;lt;math&amp;gt;\mathbf{s}&amp;lt;/math&amp;gt;, i kolumn w &amp;lt;math&amp;gt;\mathbf{D}&amp;lt;/math&amp;gt; to dostaniemy dokładnie ten sam sygnał &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Głównym wyzwaniem w analizie ICA jest estymacja macierzy mieszającej &amp;lt;math&amp;gt;\mathbf{D}&amp;lt;/math&amp;gt;. Gdy jest ona znana to komponenty mogą być wyliczone w następujący sposób:&lt;br /&gt;
: &amp;lt;math&amp;gt; \mathbf{s} = \mathbf{D}^{-1}\mathbf{x} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Estymacja ===&lt;br /&gt;
Znalezienie niezależnych komponentów może być rozważane w świetle Centralnego Twierdzenia Granicznego jako poszukiwanie komponentów o możliwie nie gaussowskim rozkładzie.&lt;br /&gt;
Aby zrozumieć to podejście prześledźmy heurystykę zaproponowaną przez (Hyvarinen, 2000). &lt;br /&gt;
Dla prostoty załóżmy, że poszukiwane źródła niezależne mają identyczne rozkłady. &lt;br /&gt;
Zdefiniujmy &amp;lt;math&amp;gt;y = \mathbf{w}^{\mathsf{T}}\mathbf{x}&amp;lt;/math&amp;gt;. Zauważmy, że jeśli &amp;lt;math&amp;gt;\mathbf{w}^{\mathsf{T}}&amp;lt;/math&amp;gt; jest jedną z kolumn macierzy &amp;lt;math&amp;gt;\mathbf{D}^{-1}&amp;lt;/math&amp;gt;, to &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; jest jednym z poszukiwanych komponentów.&lt;br /&gt;
Zamieniając zmienne &amp;lt;math&amp;gt;\mathbf{z}=\mathbf{D}^{\mathsf{T}}\mathbf{w}&amp;lt;/math&amp;gt; możemy napisać &amp;lt;math&amp;gt;y = \mathbf{w}^{\mathsf{T}}\mathbf{x} = \mathbf{w}^{\mathsf{T}} \mathbf{D}\mathbf{s} = \mathbf{z}^{\mathsf{T}}\mathbf{s}&amp;lt;/math&amp;gt;. To uwidacznia fakt, że &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; jest liniową kombinacją składowych &amp;lt;math&amp;gt;s^{i}&amp;lt;/math&amp;gt; z wagami danymi przez &amp;lt;math&amp;gt;z_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
Z centralnego twierdzenia granicznego wynika, że suma niezależnych zmiennych losowych ma  bardziej gaussowski charakter niż każda z tych zmiennych osobno. &lt;br /&gt;
Liniowa kombinacja staje się najmniej gaussowska gdy &amp;lt;math&amp;gt;\mathbf{z}&amp;lt;/math&amp;gt; ma tylko jeden element niezerowy. W tym przypadku &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; jest proporcjonalny do &amp;lt;math&amp;gt;s^{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
Zatem problem estymacji modelu ICAmoże być sformułowany jako problem znalezienia takiego &amp;lt;math&amp;gt;\mathbf{w}&amp;lt;/math&amp;gt; , który maksymalizuje niegaussowskość &amp;lt;math&amp;gt;y=\mathbf{w}^{\mathsf{T}}\mathbf{x}&amp;lt;/math&amp;gt;. &lt;br /&gt;
Maksymalizacja niegaussowskości &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; daje jeden niezależny komponent odpowiadający jednemu z &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; maksimów (bo mamy &amp;lt;math&amp;gt;s^{i}&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;-s^{i}&amp;lt;/math&amp;gt;) w krajobrazie optymalizacyjnym. Aby znaleźć wszystkie niezależne komponenty musimy znaleźć wszystkie maksima. Ponieważ komponenty są nieskorelowane, to poszukiwania kolejnych komponentów można kontynuować w podprzestrzeni ortogonalnej do już znalezionych komponentów.&lt;br /&gt;
&lt;br /&gt;
===Obliczenia===&lt;br /&gt;
Intuicyjna heurystyka poszukiwania najbardziej niegaussowskich składowych może być użyta do wyprowadzenia różnych funkcji kosztu, których optymalizacja daje model ICA, np. kurtoza. Procedura wykorzystywana w eeglabie (“runica”, Makeig 1996) dąży do minimalizacji informacji wzajemnej. Oba podejścia są w przybliżeniu równoważne (Hyvarinen, 2000), chociaż owo przybliżenie dla  sygnałów elektrofizjologicznych nie zostało to jeszcze w pełni wyeksplorowane.&lt;br /&gt;
Dla sygnałów o niskiej wymiarowości i spełniających dokładnie założenia ICA wszystkie powszechnie wykorzystywane algorytmy dają niemal identyczne wyniki.&lt;br /&gt;
&lt;br /&gt;
;Bardzo ważna uwaga: ogólną zasadą jest, że jeśli estymujemy &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; stabilnych komponentów  (z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-kanałowych danych) to musimy dysponować &amp;lt;math&amp;gt;k N^2&amp;lt;/math&amp;gt; punktami danych w każdym kanale, gdzie &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt;jest liczbą elementów w macierzy &amp;lt;math&amp;gt;\mathbf{D}&amp;lt;/math&amp;gt;, którą ICA próbuje wyestymować, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; jest liczbą całkowitą. Nie ma dobrych oszacowań teoretycznych na wielkość &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, z praktycznych obserwacji wynika, że rośnie on z ilością kanałów.&lt;br /&gt;
&lt;br /&gt;
=== Możliwe zastosowania ===&lt;br /&gt;
Najczęściej ICA jest stosowana jako narzędzie do:&lt;br /&gt;
* usuwania artefaktów z sygnałów EEG (ruchy oczu i mięśnie) &lt;br /&gt;
* wydobywania składowych do dalszej analizy (Onton, 2006)&lt;br /&gt;
* jako analiza wstępna do lokalizacji źródeł (Grau, 2007).&lt;br /&gt;
* ICA jest także stosowana w analize sygnałów EKG i EMG.&lt;br /&gt;
&lt;br /&gt;
===Bibliografia===&lt;br /&gt;
* Grau, C., Fuentemilla, L., Marco-Pallars, J. (2007). Functional neural dynamics underlying auditory event-related n1 and n1 suppression response. Neuroimage, 36(6):522–31.&lt;br /&gt;
* Hyvarinen, A. and Oja, E. (2000). Independent component analysis: Algorithms and applications. Neural Networks, 13(4-5):411–430.&lt;br /&gt;
* Makeig,S.,Bell,A.,Jung,T.-P., Sejnowski,T.(1996).Independentcomponent analysis of electroencephalographic data. W: Touretzky, D., Mozer, M., and Hasselmo, M., editors, Advances in Neural Information Processing Systems, volume 8, pages 145–151. MIT Press, Cambridge, MA.&lt;br /&gt;
* Onton,J., Makeig,S.(2006).Information-based modeling of event-related brain dynamics. Prog Brain Res., 159:99–120.&lt;br /&gt;
* Tutorial: http://sccn.ucsd.edu/wiki/Chapter_09:_Decomposing_Data_Using_ICA&lt;br /&gt;
* http://sccn.ucsd.edu/~arno/indexica.html&lt;br /&gt;
* http://cis.legacy.ics.tkk.fi/aapo/papers/IJCNN99_tutorialweb/&lt;br /&gt;
&lt;br /&gt;
=== Wydobywanie interesujących komponentów ===&lt;br /&gt;
&lt;br /&gt;
Dane do tej części ćwiczeń proszę pobrać i rozpakować w swoim katalogu:&lt;br /&gt;
http://www.fuw.edu.pl/~jarekz/LabEEG/Dane_do_ICA_alfa.tar.gz&lt;br /&gt;
&lt;br /&gt;
Pochodzą one z eksperymentu, w którym osoba badana siedziała z zamkniętymi oczami słuchając nagrania czytanego spokojnym głosem. Metadane opisujące sygnał znajdują się w pliku Miro.xml, zaś lokalizacje elektrod w pliku Miro-10-20-Cap.locs.&lt;br /&gt;
&lt;br /&gt;
Proszę:&lt;br /&gt;
* wczytać dane do eeglaba&lt;br /&gt;
* wyedytować lokalizację elektrod&lt;br /&gt;
* usunąć kanały nie zawierające EEG&lt;br /&gt;
* zmienić referencje na średnią z kanałów A1 i A2&lt;br /&gt;
* przefiltrować filtrem FIR górnoprzepustowym z częstością odcięcia 0,5 Hz&lt;br /&gt;
* obejrzeć wstępnie przygotowane dane&lt;br /&gt;
* policzyć ICA na całym sygnale &lt;br /&gt;
* obejrzeć właściwości otrzymanych komponentów&lt;br /&gt;
** Czy są wśród nich takie, które zawierają znaczny udział rytmu alfa?&lt;br /&gt;
** Jaka jest ich topografia?&lt;br /&gt;
* usunąć wszystkie komponenty nie zawierające alfy&lt;br /&gt;
* odtworzyć z tych komponentów sygnał na elektrodach&lt;br /&gt;
* wykoać dekompozycję ICA kilkukrotnie (co najmniej 3) i porównać wyniki&lt;br /&gt;
** Czy uzyskiwane komponenty są powtarzalne? &lt;br /&gt;
** Swoje wyniki porównać też z sąsiednimi grupami.&lt;br /&gt;
&lt;br /&gt;
=== Identyfikacja artefaktów ===&lt;br /&gt;
Proszę pobrać dane:&lt;br /&gt;
&lt;br /&gt;
*http://www.fuw.edu.pl/~jarekz/LabEEG/Arousal-10-20-Cap.locs&lt;br /&gt;
*http://www.fuw.edu.pl/~jarekz/LabEEG/Arousal1.set&lt;br /&gt;
*http://www.fuw.edu.pl/~jarekz/LabEEG/Arousal1.fdt&lt;br /&gt;
&lt;br /&gt;
Pochodzą one z eksprymentu w którym osoba badana czytała słowa o różych właściwościach wzbudznia emocji. &lt;br /&gt;
&lt;br /&gt;
* wczytaj je do eeglab'a&lt;br /&gt;
* wczytaj lokalizację kanałów z pliku Arousal-10-20-Cap.locs&lt;br /&gt;
* obejrzyj przebiegi czasowe&lt;br /&gt;
* odrzuć kanał z diodą (21) i z GSR (20)&lt;br /&gt;
* zrób dekompozycję ICA&lt;br /&gt;
* obejrzyj topografię komponentów. &lt;br /&gt;
* zidentyfikuj komponenty odpowiadające mruganiu i aktywności mięśniowej&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
==Filtry przestrzenne dla większej ilości warunków==&lt;br /&gt;
===FFDIAG===&lt;br /&gt;
===Analiza ERD/S z użyciem FFDIAG===&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=Laboratorium_EEG/CSP&amp;diff=5255</id>
		<title>Laboratorium EEG/CSP</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=Laboratorium_EEG/CSP&amp;diff=5255"/>
		<updated>2016-05-17T11:24:54Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Poniżej prosta demonstracja dla danych zebranych EEG przy stymulacji SSVEP z częstotliwością 38Hz. */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Laboratorium_EEG]]/BSS&lt;br /&gt;
=Ślepa separacja źródeł=&lt;br /&gt;
Rozważmy ''N''-kanałowy sygnał EEG.&lt;br /&gt;
Próbkę tego sygnału możemy przedstawić jako punkt w przestrzeni rozpiętej przez osie, z których każda reprezentuje wartość potencjału w jednym kanale. Cały sygnał tworzy w tej przestrzeni chmurę punktów. Rozciągłość tej chmury w danym kierunku mówi nam o wariancji (zmienności) sygnału w tym kierunku. &lt;br /&gt;
&lt;br /&gt;
Taki zbiór punktów wygodniej jest analizować w układzie współrzędnych zgodnym z osiami głównymi macierzy kowariancji.&lt;br /&gt;
W dalszej części rozważań założymy, że te przestrzenie, w których rozważamy sygnały są przestrzeniami wektorowymi, a pojedyncze próbki wielokanałowego sygnału są wektorami. &lt;br /&gt;
[[Plik:Kowariancja.png|200px|center]]&lt;br /&gt;
&lt;br /&gt;
==Filtry przestrzenne i ślepa separacja źródeł==&lt;br /&gt;
Sygnał EEG jest superpozycją aktywności elektrycznej wielu źródeł.&lt;br /&gt;
Jak można estymować aktywność samych źródeł?&lt;br /&gt;
[[Plik:Mieszanie.png|200px|center]]&lt;br /&gt;
Niech:&lt;br /&gt;
: &amp;lt;math&amp;gt;s(t)&amp;lt;/math&amp;gt; - aktywność niezależnych źródeł,&lt;br /&gt;
: &amp;lt;math&amp;gt;x(t)&amp;lt;/math&amp;gt; mierzony sygnał&lt;br /&gt;
: &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; macierz przejścia taka, że:&lt;br /&gt;
::&amp;lt;math&amp;gt;x(t) = A s(t)&amp;lt;/math&amp;gt; (*)&lt;br /&gt;
:&amp;lt;math&amp;gt;s(t) = A^{-1}x(t) = P x(t)&amp;lt;/math&amp;gt;&lt;br /&gt;
Macierz kowariancji dla sygnałów &amp;lt;math&amp;gt;x(t)&amp;lt;/math&amp;gt; estymujemy tak:&lt;br /&gt;
:&amp;lt;math&amp;gt; C_x = E[x(t)x(t)^T]&amp;lt;/math&amp;gt;&lt;br /&gt;
Podstawiając (*) mamy:&lt;br /&gt;
:&amp;lt;math&amp;gt; C_x = E[x x^T] = E[As(As)^T] = A E[s s^T] A^T = A C_s A^T&amp;lt;/math&amp;gt;&lt;br /&gt;
Z założenia, że źródła są niezależne wynika, że macierz &amp;lt;math&amp;gt;C_s&amp;lt;/math&amp;gt; jest diagonalna.&lt;br /&gt;
Przekształcając powyższe równanie możemy zapisać:&lt;br /&gt;
:&amp;lt;math&amp;gt;A^{-1} C_x (A^T)^{-1} = P C_x P^T = C_s&amp;lt;/math&amp;gt;&lt;br /&gt;
Odwzorowanie &amp;lt;math&amp;gt;P = A^{-1}&amp;lt;/math&amp;gt; diagonalizuje macierz &amp;lt;math&amp;gt;C_x&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Powyższe rozumowanie jest słuszne w przypadku gdy mamy do czynienia z sygnałem stacjonarnym, tzn. jego macierz kowariancji jest niezależna od czasu, czyli przez cały czas aktywna jest ta sama konfiguracja źródeł niezależnych.&lt;br /&gt;
W przypadku gdy tak nie jest to konstrukcję filtra przestrzennego można oprzeć o  jednoczesną diagonalizację macierzy kowariancji odpowiadających różnym stanom osoby badanej.&lt;br /&gt;
&lt;br /&gt;
[[Plik:Diagonalizacja.png|200px|center]]&lt;br /&gt;
&lt;br /&gt;
==Common Spatial Pattern ==&lt;br /&gt;
===Koncepcja===&lt;br /&gt;
Dla ustalenia uwagi możemy myśleć o eksperymencie wywołującym potencjał P300. Mamy w nim dwie sytuacje eksperymentalne. Oznaczmy (&amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - target) próby, w których pojawił się oczekiwany bodziec, zaś  (&amp;lt;math&amp;gt;NT&amp;lt;/math&amp;gt; - non-target) gdy pojawił się bodziec standardowy.&lt;br /&gt;
Chcielibyśmy znaleźć taki montaż, czyli taką kombinację liniową kanałów, które maksymalizuje stosunek mocy (wariancji) sygnałów rejestrowanych w dwóch rożnych warunkach eksperymentalnych. &lt;br /&gt;
&lt;br /&gt;
===Formalizm===&lt;br /&gt;
Metoda ta polega na znalezieniu takiego kierunku &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; w przestrzeni sygnałów, że sygnał z warunku &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; rzutowany na ten kierunek ma dużą wariancje a sygnał z warunku &amp;lt;math&amp;gt;NT&amp;lt;/math&amp;gt; ma wariancję małą. &lt;br /&gt;
&lt;br /&gt;
Rzutowanie sygnału &amp;lt;math&amp;gt;x(t)&amp;lt;/math&amp;gt; na kierunek &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; odbywa się przez policzenie iloczynu skalarnego dla każdej chwili czasu &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt; s_w(t) = w^T x(t)&amp;lt;/math&amp;gt;&lt;br /&gt;
Wariancja tego rzutowanego sygnału to:&lt;br /&gt;
:&amp;lt;math&amp;gt; \mathrm{var}(s_w) = E[s_w s_w^T] = E[ w^T x (w^T x)^T] = w^T E[x x^T] w = w^T C_x w &amp;lt;/math&amp;gt;&lt;br /&gt;
Zatem znalezienie właściwego kierunku rzutowania można wyrazić jako szukanie maksimum wyrażenia &amp;lt;math&amp;gt; J(w) &amp;lt;/math&amp;gt;(jest to tzw. iloraz Rayleigh'a):&lt;br /&gt;
: &amp;lt;math&amp;gt;J(w) = \frac{w^T C_T w}{w^T C_{NT} w}  &amp;lt;/math&amp;gt;&lt;br /&gt;
Ekstremum tego ilorazu można znaleźć poprzez policzenie gradientu &amp;lt;math&amp;gt;J(w)&amp;lt;/math&amp;gt; i przyrównanie go do zera:&lt;br /&gt;
:&amp;lt;math&amp;gt; \nabla J(w) =  \frac{ 1  C_{T} w+w^T C_{T} 1}{w^T C_{NT} w}-\frac{w^T  C_{T} w\left( 1  C_{NT} w+w^T C_{NT} 1\right)}{\left(w^T  C_{NT} w\right)^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
ponieważ macierze kowariancji są symetryczne &lt;br /&gt;
::&amp;lt;math&amp;gt;\nabla J(w) =   \frac{   1}{w^T  C_{NT} w}\left[    C_{T} w+ C_{T}w  -\frac{w^T  C_{T} w}{w^T  C_{NT} w} \left(   C_{NT} w+ C_{NT}w \right) \right]&amp;lt;/math&amp;gt;&lt;br /&gt;
::&amp;lt;math&amp;gt;= \frac{   2}{w^T  C_{NT} w}\left[     C_{T}w  -\frac{w^T  C_{T} w}{w^T  C_{NT} w}   C_{NT} w \right]&amp;lt;/math&amp;gt;&lt;br /&gt;
Przyrównując to wyrażenie do zera dostajemy:&lt;br /&gt;
:&amp;lt;math&amp;gt;       C_{T}w  =\frac{w^T  C_{T} w}{w^T  C_{NT} w}   C_{NT} w   &amp;lt;/math&amp;gt;&lt;br /&gt;
Liczba &amp;lt;math&amp;gt; \lambda =    \frac{w^T  C_{T} w}{w^T  C_{NT} w}   C_{NT} w &amp;lt;/math&amp;gt; jest uogólnioną wartością własną, zaś &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; jest uogólnionym wektorem własnym odpowiadającym tej wartości. &lt;br /&gt;
&lt;br /&gt;
Aby znaleźć &amp;lt;math&amp;gt; \lambda&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; wystarczy rozwiązać zagadnienie własne. W matlabie możemy w tym celu wykorzystać funkcję &amp;lt;tt&amp;gt;eig&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Odwzorowanie to można przedstawić w postaci macierzy &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;, której każdy wiersz zawiera wagi dla odpowiednich kanałów. &lt;br /&gt;
Macierz zawierająca sygnał &amp;lt;math&amp;gt;X^{\pm}(t)&amp;lt;/math&amp;gt; &lt;br /&gt;
ma wymiary &amp;lt;math&amp;gt;C \times  N&amp;lt;/math&amp;gt;, gdzie &lt;br /&gt;
&amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; to liczba kanałów EEG, natomiast &lt;br /&gt;
&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; to liczba próbek dla każdego z kanałów. &lt;br /&gt;
Macierz &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; przekształca sygnał &amp;lt;math&amp;gt;X^{\pm}(t)&amp;lt;/math&amp;gt;  zgodnie ze wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;X^{\pm}_{CSP}(t)=P^T  X^{\pm}(t) &amp;lt;/math&amp;gt;&lt;br /&gt;
Załóżmy dalej, że sygnały &amp;lt;math&amp;gt;X^{+}_{CSP} (t)&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;X^{-}_{CSP} (t)&amp;lt;/math&amp;gt; są generowane przez niezależne procesy stochastyczne, tzn. spełnione są następujące warunki. &lt;br /&gt;
# Syganły &amp;lt;math&amp;gt;X^{+}_{CSP} (t)&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;X^{-}_{CSP} (t)&amp;lt;/math&amp;gt; są niezależne.&lt;br /&gt;
# Brak korelacji pomiędzy kanałami w sygnałach&amp;lt;math&amp;gt;X^{+}_{CSP} (t)&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;X^{-}_{CSP} (t)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Przynajmniej dla jednego z kanałów wariancja przetransformowanego sygnału jest maksymalna przy wystąpieniu bodźca i minimalna przy jego braku.&lt;br /&gt;
Po przemnożeniu równania 2.3 przez &amp;lt;math&amp;gt;(X^{\pm}_{CSP} (t))^T&amp;lt;/math&amp;gt; otrzymamy macierz kowariancji przetransformowanych sygnałów uśrednioną po realizacjach:&lt;br /&gt;
:&amp;lt;math&amp;gt;R^{\pm}_{CSP} (t) = X^{\pm}_{CSP} (t)(X^{\pm}_{CSP} (t))^T = P^T X^{\pm} (t) (X^{\pm}(t))^T P = P^T R^{\pm}P&amp;lt;/math&amp;gt;  (2.4)&lt;br /&gt;
Gdzie &amp;lt;math&amp;gt;R^{\pm}&amp;lt;/math&amp;gt; to macierz kowariancji sygnału uśredniona po realizacjach. Z warunków 1 i 2 wynika, że macierze &amp;lt;math&amp;gt;R^{+}_{CSP}&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;R^{-}_{CSP}&amp;lt;/math&amp;gt; muszą być diagonalne, natomiast z warunku 3, że ich suma daje macierz jednostkową:&lt;br /&gt;
:&amp;lt;math&amp;gt;R^{+}_{CSP} + R^{-}_{CSP} = 1 &amp;lt;/math&amp;gt;  (2.5)&lt;br /&gt;
Tak więc suma par diagonalnych wartości (&amp;lt;math&amp;gt;k^{+}_{i}&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;k^{-}_{i}&amp;lt;/math&amp;gt;) w macierzach &amp;lt;math&amp;gt;R^{+}_{CSP}&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;R^{-}_{CSP}&amp;lt;/math&amp;gt; musi być równa 1.&lt;br /&gt;
Korzystając z równania 2.5 wartości na diagonali można również zapisać za pomocą wzoru:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;k^{+}_{i} = \vec{p}^{T}_{i} R^{+} \vec{p}_{i}    &amp;lt;/math&amp;gt; (2.6)&lt;br /&gt;
:&amp;lt;math&amp;gt;k^{-}_{i} = \vec{p}^T_{i} R^{-}\vec{p}_{i} &amp;lt;/math&amp;gt; (2.7)&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;\vec{p}_{i}&amp;lt;/math&amp;gt; to kolumnowy wektor macierzy &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Po przekształceniach ilorazu równań 2.6 i 2.7 można&lt;br /&gt;
otrzymać równanie:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;R^{+} \vec{p}_{i} = \frac{k^{+}_{i}}{k^{-}_{i}} R^{-} \vec{p}_{i} &amp;lt;/math&amp;gt;  (2.8)&lt;br /&gt;
￼&lt;br /&gt;
Równanie to przedstawia ogólną formę zagadnienia wartości własnych. Takie przedstawienie problemu umożliwia zastosowanie do jego rozwiązania wydajnych metod algebraicznych.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wektor własny &amp;lt;math&amp;gt;\vec{p}_i&amp;lt;/math&amp;gt; jest interpretowany jako filtr przestrzenny. Dzięki transformacie &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; sygnał zostaje przeniesiony do przestrzeni, dla której różnica wariancji dla poszczególnych klas jest największa. Zgodnie z równaniem 2.5 najbardziej różniące się od siebie kanały są skorelowane z największą wartością własną &amp;lt;math&amp;gt;k^{+}&amp;lt;/math&amp;gt;.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie symulacyjne ===&lt;br /&gt;
&amp;lt;source lang  = matlab&amp;gt;&lt;br /&gt;
% symulowany eksperyment składa się z sinusoidy udającej alfę spoczynkową i&lt;br /&gt;
% funkcji Gaussa udającego potencjał wywołany&lt;br /&gt;
% źródła te są symulowane niezależnie a potem mieszane przez macierz L&lt;br /&gt;
% symulujemy źródła&lt;br /&gt;
% s1 - symuluje alfę&lt;br /&gt;
% s2 - symuluje &amp;quot;potencjał wywołany&amp;quot; (ERP)&lt;br /&gt;
&lt;br /&gt;
%ustawiamy parametry do symulacji sygnałów&lt;br /&gt;
Fs = 100;&lt;br /&gt;
T = 1;&lt;br /&gt;
t = 0:1/Fs:T-1/Fs;&lt;br /&gt;
N_rep = 100;&lt;br /&gt;
N_chan = 2;&lt;br /&gt;
s = zeros(N_rep,N_chan, length(t));&lt;br /&gt;
X = zeros(N_rep,N_chan, length(t));&lt;br /&gt;
&lt;br /&gt;
% filtr przestrzenny - z takimi wagami trzeba wziąść kanały EEG aby odzyskać sygnały źródłowe&lt;br /&gt;
P = [1 2&lt;br /&gt;
    1.5 1.3]; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% topografie - z takimi wagami źródła dokładają się do poszczególnych elektrod&lt;br /&gt;
A = P^(-1); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
for r =1:N_rep % tworzymy kolejne realizacje &amp;quot;eksperymentu&amp;quot;&lt;br /&gt;
    s1 = sin(2*pi*11*t +pi/2+ 0*2*pi*rand())+ 0.02*randn(size(t));  % źródło alfa&lt;br /&gt;
    s2 = exp(-((t-0.8)/0.05).^2)+ 0.01*randn(size(t));              % źródło ERP&lt;br /&gt;
       &lt;br /&gt;
    s(r,1,:) = s1;&lt;br /&gt;
    s(r,2,:) = s2;&lt;br /&gt;
    tmp = squeeze(s(r,:,:));&lt;br /&gt;
    n = 0*randn(size(tmp));&lt;br /&gt;
    X(r,:,:) = A*tmp +n; % rzutujemy sygnały źródłowe na elektrody s -&amp;gt; x&lt;br /&gt;
    &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% wycinamy warunki &lt;br /&gt;
% baseline_ind   to indeksy pierwszej połowy każdego powtórzenia &amp;quot;baseline&amp;quot;&lt;br /&gt;
% ERP_ind        to indeksy drugiej połowy każdego powtórzenia zawierająca &amp;quot;ERP&amp;quot;&lt;br /&gt;
baseline_ind = find(t&amp;lt;0.5);&lt;br /&gt;
ERP_ind = find(t&amp;gt;=0.5);&lt;br /&gt;
&lt;br /&gt;
x_baseline_kan_1 = X(:,1,baseline_ind);&lt;br /&gt;
x_baseline_kan_2 = X(:,2,baseline_ind);&lt;br /&gt;
&lt;br /&gt;
x_ERP_kan_1 = X(:,1,ERP_ind);&lt;br /&gt;
x_ERP_kan_2 = X(:,2,ERP_ind);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% liczymy średnie macierze kowariancji:&lt;br /&gt;
R_E = zeros(N_chan,N_chan);&lt;br /&gt;
R_B = zeros(N_chan,N_chan);&lt;br /&gt;
for r =1:N_rep&lt;br /&gt;
    B = squeeze(X(r,:,baseline_ind)); &lt;br /&gt;
    R_B = R_B + B*B' ;&lt;br /&gt;
    &lt;br /&gt;
    E = squeeze(X(r,:,ERP_ind));&lt;br /&gt;
    R_E = R_E + E*E' ;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
R_B = R_B/N_rep;&lt;br /&gt;
R_E = R_E/N_rep;&lt;br /&gt;
&lt;br /&gt;
% rozwiązujemy uogólnione zagadnienie własne&lt;br /&gt;
[W,Lambda]=eig(R_E,R_B); % możliwa jest też optymalizacja wzg. średniej macierzy kowariancji (R_B+R_A)/2);&lt;br /&gt;
&lt;br /&gt;
% odzyskujemy sygnały źródeł&lt;br /&gt;
for r =1:N_rep&lt;br /&gt;
    S(r,:,:) = W'*squeeze(X(r,:,:));&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% pobieramy wycinki odpowiadające obu częściom eksperymentu z estymowanych&lt;br /&gt;
% źródeł&lt;br /&gt;
s_baseline_estymowany_kan1 = squeeze(  S(:,1,baseline_ind));&lt;br /&gt;
s_baseline_estymowany_kan2 = squeeze(  S(:,2,baseline_ind));&lt;br /&gt;
&lt;br /&gt;
s_ERP_estymowany_kan1 = squeeze(S(:,1,ERP_ind));&lt;br /&gt;
s_ERP_estymowany_kan2 = squeeze(S(:,2,ERP_ind));&lt;br /&gt;
&lt;br /&gt;
%%%%%%%%%%%%%% Ilustracje %%%%%%%%%%%%%%%%%%%%%%%&lt;br /&gt;
% ilustracja sygnałów mierzonych&lt;br /&gt;
figure(1);clf&lt;br /&gt;
subplot(2,2,1);&lt;br /&gt;
    plot(t(baseline_ind),(squeeze(X(:,1,baseline_ind)))','b'); hold on&lt;br /&gt;
    plot(t(ERP_ind),(squeeze(  X(:,1,ERP_ind)))','r'); hold off&lt;br /&gt;
    xlabel('elektroda 1')&lt;br /&gt;
    title('ilustracja sytuacji pomiarowej -\newline znane są potencjały na elektrodach w dwóch warunkach eksperymentalnych')&lt;br /&gt;
subplot(2,2,3);&lt;br /&gt;
    plot(t(baseline_ind),(squeeze(X(:,1,baseline_ind)))','b'); hold on&lt;br /&gt;
    plot(t(ERP_ind),(squeeze(  X(:,2,ERP_ind)))','r'); hold off&lt;br /&gt;
    xlabel('elektroda 2')&lt;br /&gt;
subplot(1,2,2)&lt;br /&gt;
    plot(x_baseline_kan_1(:),x_baseline_kan_2(:),'b.');&lt;br /&gt;
    hold on&lt;br /&gt;
    plot(x_ERP_kan_1(:),x_ERP_kan_2(:),'r.');&lt;br /&gt;
    xlim([-2,2])&lt;br /&gt;
    ylim([-2,2])&lt;br /&gt;
    axis equal&lt;br /&gt;
    &lt;br /&gt;
    % wektor własny odpowiadający największej wartości własnej jest&lt;br /&gt;
    % kierunkiem najbardziej różnicującym warunki eksperymentalne&lt;br /&gt;
    disp('wartości własne znajdują się na przekątnej macierzy Lambda')&lt;br /&gt;
    disp(Lambda)&lt;br /&gt;
    % rysujemy wersory jednostkowe w kierunkach wektorów własnych&lt;br /&gt;
    w1 = W(:,1); &lt;br /&gt;
    w1 = w1/norm(w1);&lt;br /&gt;
    w2 = W(:,2); &lt;br /&gt;
    w2 = w2/norm(w2);&lt;br /&gt;
    line([0, w1(1) ],[0,w1(2)],'Color',[0,0.3,0])&lt;br /&gt;
    text(w1(1),w1(2),'wektor własny 1')&lt;br /&gt;
    line([0, w2(1) ],[0,w2(2)],'Color',[1,0,1])&lt;br /&gt;
    text(w2(1),w2(2),'wektor własny 2')&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    xlabel('Amplituda na elektrodzie 1')&lt;br /&gt;
    ylabel('Amplituda na elektrodzie 2')   &lt;br /&gt;
    legend('baseline','ERP')&lt;br /&gt;
&lt;br /&gt;
% Ilustracja estymowanych źródeł&lt;br /&gt;
figure(2);clf&lt;br /&gt;
subplot(2,2,1);&lt;br /&gt;
    plot(t(baseline_ind),(squeeze(S(:,1,baseline_ind)))','b');hold on&lt;br /&gt;
    plot(t(ERP_ind),(squeeze(S(:,1,ERP_ind)))','r');hold off&lt;br /&gt;
    xlabel('estymowane zrodlo  1')&lt;br /&gt;
    title('ilustracja estymacji -\newline estymowane są potencjały źródeł w dwóch warunkach eksperymentalnych')    &lt;br /&gt;
subplot(2,2,3);&lt;br /&gt;
    plot(t(baseline_ind),(squeeze(S(:,2,baseline_ind)))','b');hold on&lt;br /&gt;
    plot(t(ERP_ind),(squeeze(S(:,2,ERP_ind)))','r');hold off&lt;br /&gt;
    xlabel('estymowane zrodlo  2');&lt;br /&gt;
subplot(1,2,2)&lt;br /&gt;
    plot(s_baseline_estymowany_kan1(:),s_baseline_estymowany_kan2(:),'b.');&lt;br /&gt;
    hold on&lt;br /&gt;
    plot(s_ERP_estymowany_kan1(:),s_ERP_estymowany_kan2(:),'r.');   &lt;br /&gt;
    &lt;br /&gt;
    xlabel('Amplituda estym. źródła 1')&lt;br /&gt;
    ylabel('Amplituda estym. źródła 2')   &lt;br /&gt;
    legend('baseline','ERP')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zastosowanie filtra CSP do detekcji potencjału P300==&lt;br /&gt;
===Eksperyment===&lt;br /&gt;
====Przygotowanie do badania:====&lt;br /&gt;
* założyć czepek z elektrodami w systemie 10-20;&lt;br /&gt;
* elektrody referencyjne: M1 i M2;&lt;br /&gt;
* elektroda GND w pozycji AFz.&lt;br /&gt;
&lt;br /&gt;
====Przygotowanie scenariuszy obci ====&lt;br /&gt;
* w terminalu uruchomić &amp;lt;tt&amp;gt;obci srv&amp;lt;/tt&amp;gt;;&lt;br /&gt;
* w terminalu uruchomić &amp;lt;tt&amp;gt;obci_gui --preset brain2013&amp;lt;/tt&amp;gt;;&lt;br /&gt;
* w interfejsie GUI zapisujemy scenariusze do własnego katalogu np &amp;amp;bdquo;P300&amp;amp;rdquo;&lt;br /&gt;
** &amp;amp;bdquo;P-Brain2013 Signal (with ID)&amp;amp;rdquo; jako np. &amp;amp;bdquo;Sygnal&amp;amp;rdquo;&lt;br /&gt;
** &amp;amp;bdquo;P-Brain2013 Calibration p300&amp;amp;rdquo; jako &amp;amp;bdquo;kalibracjaP300&amp;amp;rdquo;&lt;br /&gt;
** &amp;amp;bdquo;P-Brain 2013 p300&amp;amp;rdquo; jako &amp;amp;bdquo;Labirynt&amp;amp;rdquo;&lt;br /&gt;
* w przeglądarce plików otwórz katalog ~/.obci/scenarios/P300. Powinien on zawierać pliki: Sygnal.ini, kalibracjaP300.ini, Labirynt.ini oraz katalogi  Sygnal_configs, kalibracjaP300_configs, Labirynt_configs.&lt;br /&gt;
*  edytujemy parametry peerów.&lt;br /&gt;
** z katalogu ~/.obci/scenarios/P300/Sygnal_configs kopiujemy plik amplifier.ini do katalogu ~/.obci/scenarios/P300 jako global_amplifier.ini. To pozwoli nam zmieniać ustawienia wzmacniacza dla wszystkich scenariuszy jednocześnie.&lt;br /&gt;
** w naszych scenariuszach zapisanych w plikach Sygnal.ini, kalibracjaP300.ini, Labirynt.ini podmieniamy ścieżkę &amp;lt;tt&amp;gt;config =&amp;lt;/tt&amp;gt; w sekcji &amp;lt;tt&amp;gt;[peers.amplifier]&amp;lt;/tt&amp;gt; tak, aby pokazywała na ten skopiowany plik global_amplifier.ini&lt;br /&gt;
** w tym pliku global_amplifier.ini podmieniamy linijki (tak aby były to listy faktycznie wykorzystywanych kanałów) z:&lt;br /&gt;
*** &amp;lt;tt&amp;gt;active_channels&amp;lt;/tt&amp;gt;&lt;br /&gt;
*** &amp;lt;tt&amp;gt;channel_names&amp;lt;/tt&amp;gt;&lt;br /&gt;
** dodajemy też linijkę: &amp;lt;tt&amp;gt;sampling_rate = 256&amp;lt;/tt&amp;gt;&lt;br /&gt;
* wchodzimy po kolei do katalogów: Sygnal_configs, kalibracjaP300_configs, Labirynt_configs i odnajdujemy plik switch_backup.ini. W tym pliku ustawiamy parametr &amp;lt;tt&amp;gt;new_scenario&amp;lt;/tt&amp;gt; na pusty. To spowoduje, że scenariusze te nie będą uruchamiać kolejnych scenariuszy po zakończeniu działania.&lt;br /&gt;
** edytujemy plik ~/.obci/scenarios/P300/kalibracjaP300_configs/clasifier.ini &lt;br /&gt;
*** zmieniamy linię&lt;br /&gt;
::: &amp;lt;tt&amp;gt;ignore_channels = DriverSaw;AmpSaw;PO7;PO8&amp;lt;/tt&amp;gt;&lt;br /&gt;
::: na &lt;br /&gt;
::: &amp;lt;tt&amp;gt;ignore_channels = DriverSaw;AmpSaw;A1;A2&amp;lt;/tt&amp;gt;&lt;br /&gt;
::* oraz linię:&lt;br /&gt;
::: &amp;lt;tt&amp;gt;montage_channels = PO7;PO8&amp;lt;/tt&amp;gt;&lt;br /&gt;
::: na &lt;br /&gt;
::: &amp;lt;tt&amp;gt;montage_channels = A1;A2&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Przeprowadzenie badania:====&lt;br /&gt;
# Uruchom scenariusz &amp;amp;bdquo;Sygnał&amp;amp;rdquo;.&lt;br /&gt;
# Tworzy on w katalogu domowym plik o nazwie &amp;lt;tt&amp;gt;file_id_name&amp;lt;/tt&amp;gt;.&lt;br /&gt;
# Uruchamiamy Svaroga z terminala poleceniem &amp;lt;tt&amp;gt;svarog&amp;lt;/tt&amp;gt;. W zakładce sygnały on-line odnajdujemy nazwę naszego scenariusza &amp;amp;bdquo;Sygnal&amp;amp;rdquo;. Podłączamy się do niego i poprawiamy ewentualnie źle kontaktujące elektrody.&lt;br /&gt;
# Jak już jesteśmy zadowoleni z jakości sygnału to zatrzymujemy scenariusz &amp;amp;bdquo;Sygnal&amp;amp;rdquo; w obci.&lt;br /&gt;
# W pliku &amp;lt;tt&amp;gt;file_id_name&amp;lt;/tt&amp;gt;  znajduje się string, który stanowi rdzeń do tworzenia nazw plików, z których korzystają nasze scenariusze. Proszę zmienić ten string np. na: &amp;lt;tt&amp;gt;test1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
# Uruchamiamy scenariusz &amp;amp;bdquo;kalibracjaP300&amp;amp;rdquo;. Badany będzie oglądał interfejs z trzema literami A B C migającymi w losowej kolejności. Zadaniem jest zliczanie mignięć litery B.&lt;br /&gt;
# Po zakończeniu kalibracji uruchamiamy scenariusz &amp;amp;bdquo;Labirynt&amp;amp;rdquo;.&lt;br /&gt;
# Danych z kalibracji potrzebować będziemy kilka zestawów.  Proszę powtórzyć kilkukrotnie scenariusz &amp;amp;bdquo;kalibracjaP300&amp;amp;rdquo;. Przed każdym uruchomieniem trzeba zmienić string w pliku &amp;lt;tt&amp;gt;file_id_name&amp;lt;/tt&amp;gt; np. na &amp;lt;tt&amp;gt;test???&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;???&amp;lt;/tt&amp;gt; oznacza kolejne numery.&lt;br /&gt;
&lt;br /&gt;
===Analiza wstępna===&lt;br /&gt;
* Wczytać dane kalibracyjne do Matlaba i pociąć je na realizacje typu T &amp;amp;mdash; &amp;amp;bdquo;target&amp;amp;rdquo; (związane z wystąpieniami litery &amp;amp;bdquo;B&amp;amp;rdquo;) i NT &amp;amp;mdash; &amp;amp;bdquo;non-target&amp;amp;rdquo; (pozostałe litery) o długości &amp;amp;minus;200 do +800 ms wokół triggerów. Dla każdej realizacji odjąć trend liniowy.&lt;br /&gt;
* Sygnał zmontować wzgl. &amp;amp;bdquo;połączonych uszu&amp;amp;rdquo; i wyświetlić średnie przebiegi dla warunku T i NT w układzie topograficznym &amp;amp;mdash; wykorzystać w tym celu funkcję &amp;lt;tt&amp;gt;topoplot&amp;lt;/tt&amp;gt; z pakietu Eeglab.&lt;br /&gt;
&lt;br /&gt;
Poniżej zaprezentowany jest przykładowy skrypt do cięcia danych wokół znaczników. Działa on z plikami zawartymi w archiwum:&lt;br /&gt;
: [[Plik:KalibracjaP300.tar.gz]] &lt;br /&gt;
Korzysta z funkcji pomocniczych dostępnych w dystrybucji obci w katalogu &lt;br /&gt;
: /usr/share/openbci/analysis/matlab_obci_signal_processing&lt;br /&gt;
Openbci można pobrać z https://github.com/BrainTech/openbci&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = matlab&amp;gt;&lt;br /&gt;
% ustalamy nzawy plików z danymi&lt;br /&gt;
nazwaPliku = 'p_6301423_calibration_p300.obci';&lt;br /&gt;
nameOfXMLFile = strcat(nazwaPliku,'.xml');&lt;br /&gt;
nameOfTagFile = strcat(nazwaPliku,'.tag'); %tagi = znaczniki zdarzeń&lt;br /&gt;
namesOfDataFiles = strcat(nazwaPliku,'.raw');&lt;br /&gt;
&lt;br /&gt;
% inicjujemy obiekt rm&lt;br /&gt;
rm = ReadManager(nameOfXMLFile,namesOfDataFiles,nameOfTagFile);&lt;br /&gt;
&lt;br /&gt;
% obieramy przydatne parametry i znaczniki&lt;br /&gt;
numberOfChannels  = rm.get_param('number_of_channels');&lt;br /&gt;
namesOfChannels   = rm.get_param('channels_names');&lt;br /&gt;
samplingFrequency = rm.get_param('sampling_frequency');&lt;br /&gt;
tagsStruct        = rm.get_tags();&lt;br /&gt;
&lt;br /&gt;
% tworzenie list znaczników Target i NonTarget&lt;br /&gt;
numberOfStruct = length(tagsStruct);&lt;br /&gt;
targetTimeStamps = [];&lt;br /&gt;
NonTargetTimeStamps = [];&lt;br /&gt;
for structNumber = 1:numberOfStruct % iterujemy się przez tagi&lt;br /&gt;
    if(strcmp(tagsStruct(structNumber).name,'blink')) % szukamy tagów o nazwie 'blink'&lt;br /&gt;
        index = tagsStruct(structNumber).children.index; % tu jest numer pola stymulacji&lt;br /&gt;
        target= tagsStruct(structNumber).children.target;% tu jest numer pola na którym wyświetlany jest target&lt;br /&gt;
        if index == target % warunek na to, że mamy do czynienia z tagiem target&lt;br /&gt;
            targetTimeStamps = [targetTimeStamps tagsStruct(structNumber).start_timestamp]; %dodajemy timeStamp do listy targetów&lt;br /&gt;
        else&lt;br /&gt;
            NonTargetTimeStamps = [NonTargetTimeStamps tagsStruct(structNumber).start_timestamp];%dodajemy timeStamp do listy non-targetów&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% pobieramy próbki&lt;br /&gt;
samples = double(rm.get_samples()); % konwersja na double jest potrzebna żeby dobrze funkcjonowało filtrowanie&lt;br /&gt;
samples=samples(1:8,:); % odrzucamy kanały, które nie mają EEG&lt;br /&gt;
numberOfChannels =8;&lt;br /&gt;
&lt;br /&gt;
% filtrujemy dolnoprzepustowo aby odrzucić artefakty sieci i część&lt;br /&gt;
% artefaktów mięśniowych&lt;br /&gt;
[b,a] = cheby2(6,80,25 /(samplingFrequency/2),'low');&lt;br /&gt;
for ch = 1:numberOfChannels&lt;br /&gt;
    samples(ch,:)=filtfilt(b,a,samples(ch,:));&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% montujemy dane do wspólnej średniej (common average)&lt;br /&gt;
M = -ones(8,8)/8;&lt;br /&gt;
M=M+eye(8,8)*9/8;&lt;br /&gt;
samples = 0.0715*M*samples;&lt;br /&gt;
&lt;br /&gt;
% wycinamy dane wokół znaczników&lt;br /&gt;
PRE = -0.2; % czas przed tagiem w sek.&lt;br /&gt;
POST = 0.8; % czas po tagu w sek.&lt;br /&gt;
wycinek = floor(PRE*samplingFrequency:POST*samplingFrequency); % tablica ze &amp;quot;standardowymi&amp;quot; indeksami do cięcia&lt;br /&gt;
&lt;br /&gt;
% pobieramy targety&lt;br /&gt;
TargetSignal = zeros(length(targetTimeStamps),numberOfChannels, length(wycinek)); % tablica na sygnały target&lt;br /&gt;
for trialNumber = 1:length(targetTimeStamps)&lt;br /&gt;
    trigerOnset = floor(targetTimeStamps(trialNumber)*samplingFrequency);&lt;br /&gt;
    tenWycinek = wycinek + trigerOnset;&lt;br /&gt;
    if tenWycinek(1)&amp;gt;0 &amp;amp;&amp;amp; tenWycinek(end)&amp;lt;=size(samples,2) % test czy wycinek który chcemy pobrać nie wystaje poza dostępny sygnał&lt;br /&gt;
        tmpSignal = samples(:,tenWycinek);&lt;br /&gt;
        tmpSignal = detrend(tmpSignal')'; % usuwanie liniowego trendu - przy krótkich wycinkach działa lepiej niż filtrowanie górnoprzepustowe&lt;br /&gt;
        TargetSignal(trialNumber, :,:) = tmpSignal;&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% pobieramy non-targety&lt;br /&gt;
NonTargetSignal = zeros(length(NonTargetTimeStamps),numberOfChannels, length(wycinek));% tablica na sygnały non-target&lt;br /&gt;
for trialNumber = 1:length(NonTargetTimeStamps)&lt;br /&gt;
    trigerOnset = floor(NonTargetTimeStamps(trialNumber)*samplingFrequency);&lt;br /&gt;
    tenWycinek = wycinek + trigerOnset;&lt;br /&gt;
    if tenWycinek(1)&amp;gt;0 &amp;amp;&amp;amp; tenWycinek(end)&amp;lt;=size(samples,2)&lt;br /&gt;
        tmpSignal = samples(:,tenWycinek);&lt;br /&gt;
        tmpSignal = detrend(tmpSignal')';&lt;br /&gt;
        NonTargetSignal(trialNumber, :,:) = tmpSignal;&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
%&lt;br /&gt;
% dla ilustracji podglądamy średnie po powtórzeniach ze wszystkich targetów&lt;br /&gt;
% i non-targetów&lt;br /&gt;
plot(squeeze(mean(TargetSignal,1))','r');&lt;br /&gt;
hold on&lt;br /&gt;
plot(squeeze(mean(NonTargetSignal,1))','b')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Analiza CSP===&lt;br /&gt;
* Korzystając z danych kalibracyjnych wykonać analizę CSP wzmacniającą potencjał P300.&lt;br /&gt;
* Zaprezentować średnią ze wszystkich kanałów źródłowych z warunku target (jeden kolor) i non-target (inny kolor) w subplotach ułożonych w prostokątnej siatce. Zaobserwować dla którego kanału średnie różnią się najbardziej. Czy jest związek tego kanału z wartościami własnymi?&lt;br /&gt;
&lt;br /&gt;
* Dla kanału najbardziej różnicującego wykonać mapki topograficzne wektorów odpowiadających:&lt;br /&gt;
** filtrowi przestrzennemu &lt;br /&gt;
** rzutu topograficznego źródła na elektrody.&lt;br /&gt;
* Do wykonania tych mapek wykorzystać funkcję &amp;lt;tt&amp;gt;topoplot&amp;lt;/tt&amp;gt; z pakietu &amp;lt;tt&amp;gt;eeglab&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Zbadać powtarzalność topografii pomiędzy plikami konfiguracyjnymi.&lt;br /&gt;
&lt;br /&gt;
===Wybór i separacja cech===&lt;br /&gt;
* Przedstaw na rysunkach nałożone na siebie pojedyncze realizacje z warunków target i non-target po rzutowaniu na wektor &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; odpowiadający największej i kolejnej wartości  własnej. &lt;br /&gt;
* Przedstaw wykresy punktowe, takie że na jednej osi jest moc sygnału odpowiadającego największej wartości własnej a na drugiej osi kolejnej wartości własnej; jeden punkt reprezentuje jedno powtórzenie.&lt;br /&gt;
* Wykonaj serię wykresów jak w poprzednim punkcie dla uśrednień kolejno po 2, 4, 6, 8 i 10 realizacjach. Zaobserwuj jak zmienia się separacja w grupach target i non-target.&lt;br /&gt;
&lt;br /&gt;
==Filtry przestrzenne dla SSEP ==&lt;br /&gt;
&lt;br /&gt;
=== Teoria===&lt;br /&gt;
Ciekawa koncepcja filtra przestrzennego dla SSVEP zaprezentowana jest  tu: http://www.eurasip.org/Proceedings/Eusipco/Eusipco2009/contents/papers/1569193209.pdf&lt;br /&gt;
&lt;br /&gt;
Po krótce można ją rozumieć podobnie do tego co robiliśmy rozważając filtry przestrzenne CSP, z tym, że dla SSVEP oraz innych potencjałów wywołanych stanu ustalonego możemy skorzystać z dodatkowych informacji dotyczących poszukiwanych źródeł. Wiemy mianowicie, że powinny one oscylować z częstością bodźca, i być może jej harmonicznych.&lt;br /&gt;
&lt;br /&gt;
Przyda nam się macierz &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; zbudowana tak, że w kolejnych kolumnach znajdują się sinusy i cosinusy kolejnych częstości harmonicznych. Wektory te unormujemy, żeby miały energię równą 1. Innymi słowy macierz &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; zbudowana jest z wersorów rozpinających przestrzeń, w której powinien znajdować się sygnał SSVEP.&lt;br /&gt;
&lt;br /&gt;
W matlabie możemy taką macierz zbudować tak:&lt;br /&gt;
&amp;lt;source lang = matlab&amp;gt;&lt;br /&gt;
% Fs - częstość próbkowania&lt;br /&gt;
% numberOfSamples - długość sygnału w próbkach&lt;br /&gt;
% numberOfHarmonics - liczba harmonicznych, które chcemy włączyć do analizy&lt;br /&gt;
t = (0:1:numberOfSamples - 1)/Fs; &lt;br /&gt;
S = zeros(numberOfSamples, 2*numberOfHarmonics);&lt;br /&gt;
&lt;br /&gt;
for harmonicNumber = 1:numberOfHarmonics&lt;br /&gt;
    c = cos(2*pi*stimulationFrequency*harmonicNumber*t);&lt;br /&gt;
    s = sin(2*pi*stimulationFrequency*harmonicNumber*t);&lt;br /&gt;
    S(:,(harmonicNumber - 1)*2 + 1) = c/norm(c);&lt;br /&gt;
    S(:,(harmonicNumber - 1)*2 + 2) = s/norm(s);&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aby w badanym sygnale znaleźć składowe odpowiadające SSVEP musimy rzutować sygnał &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; (macierz sygnałów ''kanały x próbki'')  na przestrzeń rozpiętą przez &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;A = X*S&amp;lt;/math&amp;gt;&lt;br /&gt;
Macierz &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; zawiera współczynniki będące iloczynami skalarnymi sygnałów i wersorów. Mówią one o tym &amp;quot;jak duże&amp;quot; jest sinusa bądź cosinusa o danej częstości w pierwotnym sygnale. Komponenty SSVEP zawarte w sygnale &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; odzyskujemy tak:&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathrm{SSVEP} = A S^T&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Modelujemy rejestrowany sygnał jako:&lt;br /&gt;
:&amp;lt;math&amp;gt;X = \mathrm{SSVEP} + Y &amp;lt;/math&amp;gt;&lt;br /&gt;
gdzie: &lt;br /&gt;
:&amp;lt;math&amp;gt;Y = X-\mathrm{SSVEP}&amp;lt;/math&amp;gt; &lt;br /&gt;
: to wszystkie komponenty sygnału, które nas nie interesują.&lt;br /&gt;
&lt;br /&gt;
Filtr przestrzenny, który chcemy zbudować powinien maksymalizować stosunek wariancji &amp;lt;math&amp;gt;\mathrm{SSVEP} = A S^T&amp;lt;/math&amp;gt; do wariancji &amp;lt;math&amp;gt;Y = X-\mathrm{SSVEP}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Dalej możemy zastosować technikę znaną z konstrukcji filtrów CSP, tzn. maksymalizacji ilorazu Rayleigh'a za pomocą rozwiązania ogólnionego zagadnienia własnego dla macierzy kowariancji &amp;lt;math&amp;gt;\mathrm{SSVEP} &amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;Y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Poniżej prosta demonstracja dla danych zebranych EEG przy stymulacji SSVEP z częstotliwością 38Hz.===&lt;br /&gt;
Spakowane dane: [[Plik:PrzykladoweDaneSSVEP.mat.gz]].&lt;br /&gt;
W oparciu o powyższy opis proszę zaimplementować  funkcję &amp;lt;tt&amp;gt;cosSinCSP&amp;lt;/tt&amp;gt;. Prawidłowo zaimplementowana funkcja wraz z poniższym kodem powinna generować rysunek:&lt;br /&gt;
[[Plik:Rys_SSVEP_demo.png|400px|thumb|right|podpis grafiki]] &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = matlab&amp;gt;&lt;br /&gt;
% wczytujemy dane&lt;br /&gt;
load('PrzykladoweDaneSSVEP.mat');&lt;br /&gt;
&lt;br /&gt;
[numberOfTrials numberOfChannels numberOfSamples] = size(X.data);&lt;br /&gt;
namesOfChannels = X.channels;&lt;br /&gt;
 &lt;br /&gt;
% numberOfChannels numberOfSamples numberOfTrials&lt;br /&gt;
W = zeros(numberOfChannels,numberOfChannels);&lt;br /&gt;
numberOfHarmonics = 3;&lt;br /&gt;
signal = X.data; % (  powtórzenie,  kanał, próbki)&lt;br /&gt;
 &lt;br /&gt;
S = zeros(size(signal));&lt;br /&gt;
W = cosSinCSP(signal,X.stimulation,numberOfHarmonics,X.sampling);&lt;br /&gt;
for powt = 1:size(signal,1)&lt;br /&gt;
    S(powt,:,:) = W'*squeeze(signal(powt,:,:));&lt;br /&gt;
end&lt;br /&gt;
 &lt;br /&gt;
figure('Name',['Stymulacja: ',num2str(X.stimulation),' Hz'])&lt;br /&gt;
for i =1:numberOfChannels&lt;br /&gt;
    % rysujemy widma uśrednione po realizacjach dla danych &lt;br /&gt;
    % z oryginalnych kanałów EEG&lt;br /&gt;
    subplot(2,8,i)&lt;br /&gt;
    PP=0;&lt;br /&gt;
    for rep = 1:numberOfTrials&lt;br /&gt;
        x = signal(rep,i,:);&lt;br /&gt;
        [Pxx,ff] = pwelch(x, X.sampling, 1, X.sampling, X.sampling);&lt;br /&gt;
        PP =PP + Pxx;&lt;br /&gt;
    end&lt;br /&gt;
    plot(ff(ff&amp;lt;60),PP(ff&amp;lt;60))&lt;br /&gt;
    title(namesOfChannels{i})&lt;br /&gt;
 &lt;br /&gt;
    % rysujemy widma uśrednione po realizacjach dla danych &lt;br /&gt;
    % z estymowanych źródeł CSP&lt;br /&gt;
    subplot(2,8,8+i)&lt;br /&gt;
    PP=0;&lt;br /&gt;
    for rep = 1:numberOfTrials&lt;br /&gt;
        s = S(rep,i,:);&lt;br /&gt;
        [Pss,ff]=pwelch(s, X.sampling, 1, X.sampling, X.sampling);&lt;br /&gt;
        PP =PP + Pss;&lt;br /&gt;
    end&lt;br /&gt;
    plot(ff(ff&amp;lt;60),PP(ff&amp;lt;60))&lt;br /&gt;
    title(['źródło CSP: ', num2str(i)])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przykładowy skrypt i dane prezentujący konstrukcję i działanie tego typu filtrów przestrzennych dla pełnych danych z eksperymentu SSVEP: [[Plik:SSVEP_demo_csp.tar.gz]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===Eksperyment ASSR===&lt;br /&gt;
W eksprymencie wykorzystujemy układ do generacji potencjałów słuchowych stanu ustalonego (ASSR). Wejście układu ASSR typu mini-jack wkładamy w wyjście słuchawkowe w laptopie. Drugie wejście układu ASSR wkładamy do wyjścia triggera we wzmacniaczu. Uruchamiamy plik dźwiękowy MM40tr.wav. Można go znalezc w: http://www.fuw.edu.pl/~suffa/LabEEG/MM40tr.wav&lt;br /&gt;
&lt;br /&gt;
Stymulacja dźwiękowa składa sie z fali nośnej o częstości 400 Hz modulowanej z częstością 40 Hz. Plik dźwiękowy zawiera 5 sekund ciszy i 5 sekund stymulacji, powtórzone 40 razy.&lt;br /&gt;
&lt;br /&gt;
====Rejestracja sygnału====&lt;br /&gt;
# Zakładamy czepek i elektrody w systemie 10-10, dbamy o to by opory pomiędzy elektrodami były poniżej 5 k&amp;amp;Omega; i różnice pomiędzy oporami różnych elektrod nie przekraczały 20%.&lt;br /&gt;
# Oklejamy kwadrat 3&amp;amp;times;3 elektrod na korze słuchowej z lewej strony (elektrody FT7, FC5, FC3, T7, C5, T3, TP7, CP5, CP3), 3&amp;amp;times;3 elektrod na korze słuchowej z prawej strony (elektrody FT8, FC6, FC4, T8, C6, T4, TP8, CP6, CP4), elektrody Fz, Cz, Pz i Oz, elektrody referencyjne A1 i A2. W sumie powinno być 24 elektrody.&lt;br /&gt;
# Elektrodę GND mocujemy na pozycji AFz.&lt;br /&gt;
# Sygnał rejestrujemy z częstością 2048 Hz.&lt;br /&gt;
# Do rejestracji stosujemy scenariusz 'ASSR' w interfejsie obci_gui.&lt;br /&gt;
&lt;br /&gt;
====Analiza====&lt;br /&gt;
 JZ: zmieniłbym analizę na czas-częstość i zrobił porównanie montażu usznego do filtra G.G. Moliny&lt;br /&gt;
&lt;br /&gt;
Początek stymulacji dźwiękowej oznaczymy jako 0. Poniższą analizę zastosuj dla sygnałów w referencji do uśrednionych odprowadzeń usznych A1 i A2.&lt;br /&gt;
Wyznaczenie pasma częstości odpowiedzi ASSR&lt;br /&gt;
# Z sygnału wycinamy fragmenty od 0 do 5 sek. dla wszystkich elektrod położone nad korą słuchową.&lt;br /&gt;
# Dla każdej realizacji obliczamy widma metodą Welcha.&lt;br /&gt;
# Otrzymane zespolone widma uśredniamy po realizacjach.&lt;br /&gt;
# Sprawdzamy czy w uśrednionym widmie występuję maksimum w częstości modulacji tj. 40 Hz.&lt;br /&gt;
&lt;br /&gt;
====Wyznaczenie przebiegu czasowego ERD i ERS====&lt;br /&gt;
# Zaprojektuj filtry pasmowo przepustowe (Czebyszewa 2 rodzaju) zgodne z wyznaczonym pasmem. Zbadaj funkcje przenoszenia i odpowiedzi impulsowej.&lt;br /&gt;
# Powycinaj sygnały od &amp;amp;minus;5 do +10 sekund (wszystkie kanały). Przefiltruj każdą realizację.&lt;br /&gt;
# Oblicz moc chwilową za pomocą transformaty Hilberta (kwadrat modułu transformaty Hilberta).&lt;br /&gt;
# Uśrednij moc chwilową po realizacjach.&lt;br /&gt;
# Oblicz względną zmianę mocy chwilowej względem czasu &amp;amp;minus;4 do &amp;amp;minus;2 s. W ten sposób otrzymasz przebieg ERD i ERS w czasie.&lt;br /&gt;
# Wykreśl ERD i ERS w układzie topograficznym. (Rozmieść subploty tak, aby z w przybliżeniu odpowiadały pozycjom elektrod).&lt;br /&gt;
&lt;br /&gt;
====Transformacja Hjortha====&lt;br /&gt;
Transformacja Hjortha jest przybliżeniem numerycznym transformacji Laplace'a, czyli drugiej pochodnej przestrzennej. Obliczamy ją jako różnicę potencjału pomiędzy daną elektrodą i średnią z czterech sąsiednich elektrod.&lt;br /&gt;
Przelicz potencjały z elektrod, w których występuję odpowiedź ASSR na montaż Hjortha i powtórz analizę ERD/ERS opisaną powyżej.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==ICA jako filtr przestrzenny==&lt;br /&gt;
===Definicja ===&lt;br /&gt;
Independent Component Analysis (ICA) jest metodą statystycznej analizy sygnałów, która dokonuje dekompozycji wielokanałowych zapisów na składowe niezależne w sensie statystycznym.&lt;br /&gt;
Dwie składowe &amp;lt;math&amp;gt;s_{1}&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;s_{2}&amp;lt;/math&amp;gt; są niezależne jeżeli wiedza o wartości &amp;lt;math&amp;gt;s_{1}&amp;lt;/math&amp;gt; nie daje żadnych informacji o możliwych wartościach &amp;lt;math&amp;gt;s_{2}&amp;lt;/math&amp;gt;. ICA może być wyrażona przez prosty model generatywny:&lt;br /&gt;
: &amp;lt;math&amp;gt; \mathbf{x} = \mathbf{D}\mathbf{s} &amp;lt;/math&amp;gt;&lt;br /&gt;
: gdzie &amp;lt;math&amp;gt;\mathbf{x}=\{x^{1},x^{2},\dots, x^{n}\}&amp;lt;/math&amp;gt; jest zmierzonym &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; kanałowym sygnałem, &amp;lt;math&amp;gt;\mathbf{D}&amp;lt;/math&amp;gt; jest macierzą mieszającą zaś &amp;lt;math&amp;gt;\mathbf{s}=\{s^{1},s^{2},\dots,s^{n} \}&amp;lt;/math&amp;gt; jest aktywnością  &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; źródeł. Podstawowym założeniem dotyczącym &amp;lt;math&amp;gt;\mathbf{s}&amp;lt;/math&amp;gt; jest to, że &amp;lt;math&amp;gt;s^{i}&amp;lt;/math&amp;gt; są statystycznie niezależne.  Aby wyestymować model musimy też założyć, że składowe mają niegaussowskie rozkłady wartości (Hyvarinen, 2000).&lt;br /&gt;
&lt;br /&gt;
Dodatkowo model ten zakłada następujące fakty:&lt;br /&gt;
# Sygnał jest liniową mieszaniną aktywności źródeł&lt;br /&gt;
# Sygnały pochodzące z każdego ze źródeł są niezależne od pozostałych&lt;br /&gt;
# Źródła oraz proces ich mieszania są stacjonarne, tzn, ich momenty statystyczne nie zależą od czasu&lt;br /&gt;
# Energie (wariancje) źródeł nie mogą być wyznaczone jednoznacznie. Dzieje się tak ponieważ pomnożenie amplitudy &amp;lt;math&amp;gt;i-{tego}&amp;lt;/math&amp;gt; źródła może być uzyskane poprzez przemnożenie albo &amp;lt;math&amp;gt;s^{i}&amp;lt;/math&amp;gt; albo przez przemnożenie  &amp;lt;math&amp;gt;i-tej&amp;lt;/math&amp;gt; kolumny macierzy &amp;lt;math&amp;gt;\mathbf{D}&amp;lt;/math&amp;gt;}.  Naturalnym rozwiązaniem tej niejednoznaczności jest wprowadzenie konwencji, że komponenty są normowane tak aby miały wariancję 1: &amp;lt;math&amp;gt;E[s^{i}]=1&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Kolejność komponentów jest dowolna.  Bo jeśli: w ten sam sposób zmienimy kolejność komponentów w &amp;lt;math&amp;gt;\mathbf{s}&amp;lt;/math&amp;gt;, i kolumn w &amp;lt;math&amp;gt;\mathbf{D}&amp;lt;/math&amp;gt; to dostaniemy dokładnie ten sam sygnał &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Głównym wyzwaniem w analizie ICA jest estymacja macierzy mieszającej &amp;lt;math&amp;gt;\mathbf{D}&amp;lt;/math&amp;gt;. Gdy jest ona znana to komponenty mogą być wyliczone w następujący sposób:&lt;br /&gt;
: &amp;lt;math&amp;gt; \mathbf{s} = \mathbf{D}^{-1}\mathbf{x} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Estymacja ===&lt;br /&gt;
Znalezienie niezależnych komponentów może być rozważane w świetle Centralnego Twierdzenia Granicznego jako poszukiwanie komponentów o możliwie nie gaussowskim rozkładzie.&lt;br /&gt;
Aby zrozumieć to podejście prześledźmy heurystykę zaproponowaną przez (Hyvarinen, 2000). &lt;br /&gt;
Dla prostoty załóżmy, że poszukiwane źródła niezależne mają identyczne rozkłady. &lt;br /&gt;
Zdefiniujmy &amp;lt;math&amp;gt;y = \mathbf{w}^{\mathsf{T}}\mathbf{x}&amp;lt;/math&amp;gt;. Zauważmy, że jeśli &amp;lt;math&amp;gt;\mathbf{w}^{\mathsf{T}}&amp;lt;/math&amp;gt; jest jedną z kolumn macierzy &amp;lt;math&amp;gt;\mathbf{D}^{-1}&amp;lt;/math&amp;gt;, to &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; jest jednym z poszukiwanych komponentów.&lt;br /&gt;
Zamieniając zmienne &amp;lt;math&amp;gt;\mathbf{z}=\mathbf{D}^{\mathsf{T}}\mathbf{w}&amp;lt;/math&amp;gt; możemy napisać &amp;lt;math&amp;gt;y = \mathbf{w}^{\mathsf{T}}\mathbf{x} = \mathbf{w}^{\mathsf{T}} \mathbf{D}\mathbf{s} = \mathbf{z}^{\mathsf{T}}\mathbf{s}&amp;lt;/math&amp;gt;. To uwidacznia fakt, że &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; jest liniową kombinacją składowych &amp;lt;math&amp;gt;s^{i}&amp;lt;/math&amp;gt; z wagami danymi przez &amp;lt;math&amp;gt;z_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
Z centralnego twierdzenia granicznego wynika, że suma niezależnych zmiennych losowych ma  bardziej gaussowski charakter niż każda z tych zmiennych osobno. &lt;br /&gt;
Liniowa kombinacja staje się najmniej gaussowska gdy &amp;lt;math&amp;gt;\mathbf{z}&amp;lt;/math&amp;gt; ma tylko jeden element niezerowy. W tym przypadku &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; jest proporcjonalny do &amp;lt;math&amp;gt;s^{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
Zatem problem estymacji modelu ICAmoże być sformułowany jako problem znalezienia takiego &amp;lt;math&amp;gt;\mathbf{w}&amp;lt;/math&amp;gt; , który maksymalizuje niegaussowskość &amp;lt;math&amp;gt;y=\mathbf{w}^{\mathsf{T}}\mathbf{x}&amp;lt;/math&amp;gt;. &lt;br /&gt;
Maksymalizacja niegaussowskości &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; daje jeden niezależny komponent odpowiadający jednemu z &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; maksimów (bo mamy &amp;lt;math&amp;gt;s^{i}&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;-s^{i}&amp;lt;/math&amp;gt;) w krajobrazie optymalizacyjnym. Aby znaleźć wszystkie niezależne komponenty musimy znaleźć wszystkie maksima. Ponieważ komponenty są nieskorelowane, to poszukiwania kolejnych komponentów można kontynuować w podprzestrzeni ortogonalnej do już znalezionych komponentów.&lt;br /&gt;
&lt;br /&gt;
===Obliczenia===&lt;br /&gt;
Intuicyjna heurystyka poszukiwania najbardziej niegaussowskich składowych może być użyta do wyprowadzenia różnych funkcji kosztu, których optymalizacja daje model ICA, np. kurtoza. Procedura wykorzystywana w eeglabie (“runica”, Makeig 1996) dąży do minimalizacji informacji wzajemnej. Oba podejścia są w przybliżeniu równoważne (Hyvarinen, 2000), chociaż owo przybliżenie dla  sygnałów elektrofizjologicznych nie zostało to jeszcze w pełni wyeksplorowane.&lt;br /&gt;
Dla sygnałów o niskiej wymiarowości i spełniających dokładnie założenia ICA wszystkie powszechnie wykorzystywane algorytmy dają niemal identyczne wyniki.&lt;br /&gt;
&lt;br /&gt;
;Bardzo ważna uwaga: ogólną zasadą jest, że jeśli estymujemy &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; stabilnych komponentów  (z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-kanałowych danych) to musimy dysponować &amp;lt;math&amp;gt;k N^2&amp;lt;/math&amp;gt; punktami danych w każdym kanale, gdzie &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt;jest liczbą elementów w macierzy &amp;lt;math&amp;gt;\mathbf{D}&amp;lt;/math&amp;gt;, którą ICA próbuje wyestymować, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; jest liczbą całkowitą. Nie ma dobrych oszacowań teoretycznych na wielkość &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, z praktycznych obserwacji wynika, że rośnie on z ilością kanałów.&lt;br /&gt;
&lt;br /&gt;
=== Możliwe zastosowania ===&lt;br /&gt;
Najczęściej ICA jest stosowana jako narzędzie do:&lt;br /&gt;
* usuwania artefaktów z sygnałów EEG (ruchy oczu i mięśnie) &lt;br /&gt;
* wydobywania składowych do dalszej analizy (Onton, 2006)&lt;br /&gt;
* jako analiza wstępna do lokalizacji źródeł (Grau, 2007).&lt;br /&gt;
* ICA jest także stosowana w analize sygnałów EKG i EMG.&lt;br /&gt;
&lt;br /&gt;
===Bibliografia===&lt;br /&gt;
* Grau, C., Fuentemilla, L., Marco-Pallars, J. (2007). Functional neural dynamics underlying auditory event-related n1 and n1 suppression response. Neuroimage, 36(6):522–31.&lt;br /&gt;
* Hyvarinen, A. and Oja, E. (2000). Independent component analysis: Algorithms and applications. Neural Networks, 13(4-5):411–430.&lt;br /&gt;
* Makeig,S.,Bell,A.,Jung,T.-P., Sejnowski,T.(1996).Independentcomponent analysis of electroencephalographic data. W: Touretzky, D., Mozer, M., and Hasselmo, M., editors, Advances in Neural Information Processing Systems, volume 8, pages 145–151. MIT Press, Cambridge, MA.&lt;br /&gt;
* Onton,J., Makeig,S.(2006).Information-based modeling of event-related brain dynamics. Prog Brain Res., 159:99–120.&lt;br /&gt;
* Tutorial: http://sccn.ucsd.edu/wiki/Chapter_09:_Decomposing_Data_Using_ICA&lt;br /&gt;
* http://sccn.ucsd.edu/~arno/indexica.html&lt;br /&gt;
* http://cis.legacy.ics.tkk.fi/aapo/papers/IJCNN99_tutorialweb/&lt;br /&gt;
&lt;br /&gt;
=== Wydobywanie interesujących komponentów ===&lt;br /&gt;
&lt;br /&gt;
Dane do tej części ćwiczeń proszę pobrać i rozpakować w swoim katalogu:&lt;br /&gt;
http://www.fuw.edu.pl/~jarekz/LabEEG/Dane_do_ICA_alfa.tar.gz&lt;br /&gt;
&lt;br /&gt;
Pochodzą one z eksperymentu, w którym osoba badana siedziała z zamkniętymi oczami słuchając nagrania czytanego spokojnym głosem. Metadane opisujące sygnał znajdują się w pliku Miro.xml, zaś lokalizacje elektrod w pliku Miro-10-20-Cap.locs.&lt;br /&gt;
&lt;br /&gt;
Proszę:&lt;br /&gt;
* wczytać dane do eeglaba&lt;br /&gt;
* wyedytować lokalizację elektrod&lt;br /&gt;
* usunąć kanały nie zawierające EEG&lt;br /&gt;
* zmienić referencje na średnią z kanałów A1 i A2&lt;br /&gt;
* przefiltrować filtrem FIR górnoprzepustowym z częstością odcięcia 0,5 Hz&lt;br /&gt;
* obejrzeć wstępnie przygotowane dane&lt;br /&gt;
* policzyć ICA na całym sygnale &lt;br /&gt;
* obejrzeć właściwości otrzymanych komponentów&lt;br /&gt;
** Czy są wśród nich takie, które zawierają znaczny udział rytmu alfa?&lt;br /&gt;
** Jaka jest ich topografia?&lt;br /&gt;
* usunąć wszystkie komponenty nie zawierające alfy&lt;br /&gt;
* odtworzyć z tych komponentów sygnał na elektrodach&lt;br /&gt;
* wykoać dekompozycję ICA kilkukrotnie (co najmniej 3) i porównać wyniki&lt;br /&gt;
** Czy uzyskiwane komponenty są powtarzalne? &lt;br /&gt;
** Swoje wyniki porównać też z sąsiednimi grupami.&lt;br /&gt;
&lt;br /&gt;
=== Identyfikacja artefaktów ===&lt;br /&gt;
Proszę pobrać dane:&lt;br /&gt;
&lt;br /&gt;
*http://www.fuw.edu.pl/~jarekz/LabEEG/Arousal-10-20-Cap.locs&lt;br /&gt;
*http://www.fuw.edu.pl/~jarekz/LabEEG/Arousal1.set&lt;br /&gt;
*http://www.fuw.edu.pl/~jarekz/LabEEG/Arousal1.fdt&lt;br /&gt;
&lt;br /&gt;
Pochodzą one z eksprymentu w którym osoba badana czytała słowa o różych właściwościach wzbudznia emocji. &lt;br /&gt;
&lt;br /&gt;
* wczytaj je do eeglab'a&lt;br /&gt;
* wczytaj lokalizację kanałów z pliku Arousal-10-20-Cap.locs&lt;br /&gt;
* obejrzyj przebiegi czasowe&lt;br /&gt;
* odrzuć kanał z diodą (21) i z GSR (20)&lt;br /&gt;
* zrób dekompozycję ICA&lt;br /&gt;
* obejrzyj topografię komponentów. &lt;br /&gt;
* zidentyfikuj komponenty odpowiadające mruganiu i aktywności mięśniowej&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
==Filtry przestrzenne dla większej ilości warunków==&lt;br /&gt;
===FFDIAG===&lt;br /&gt;
===Analiza ERD/S z użyciem FFDIAG===&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=Laboratorium_EEG/CSP&amp;diff=5254</id>
		<title>Laboratorium EEG/CSP</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=Laboratorium_EEG/CSP&amp;diff=5254"/>
		<updated>2016-05-17T10:25:16Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Poniżej prosta demonstracja dla danych zebranych EEG przy stymulacji SSVEP z częstotliwością 38Hz. */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Laboratorium_EEG]]/BSS&lt;br /&gt;
=Ślepa separacja źródeł=&lt;br /&gt;
Rozważmy ''N''-kanałowy sygnał EEG.&lt;br /&gt;
Próbkę tego sygnału możemy przedstawić jako punkt w przestrzeni rozpiętej przez osie, z których każda reprezentuje wartość potencjału w jednym kanale. Cały sygnał tworzy w tej przestrzeni chmurę punktów. Rozciągłość tej chmury w danym kierunku mówi nam o wariancji (zmienności) sygnału w tym kierunku. &lt;br /&gt;
&lt;br /&gt;
Taki zbiór punktów wygodniej jest analizować w układzie współrzędnych zgodnym z osiami głównymi macierzy kowariancji.&lt;br /&gt;
W dalszej części rozważań założymy, że te przestrzenie, w których rozważamy sygnały są przestrzeniami wektorowymi, a pojedyncze próbki wielokanałowego sygnału są wektorami. &lt;br /&gt;
[[Plik:Kowariancja.png|200px|center]]&lt;br /&gt;
&lt;br /&gt;
==Filtry przestrzenne i ślepa separacja źródeł==&lt;br /&gt;
Sygnał EEG jest superpozycją aktywności elektrycznej wielu źródeł.&lt;br /&gt;
Jak można estymować aktywność samych źródeł?&lt;br /&gt;
[[Plik:Mieszanie.png|200px|center]]&lt;br /&gt;
Niech:&lt;br /&gt;
: &amp;lt;math&amp;gt;s(t)&amp;lt;/math&amp;gt; - aktywność niezależnych źródeł,&lt;br /&gt;
: &amp;lt;math&amp;gt;x(t)&amp;lt;/math&amp;gt; mierzony sygnał&lt;br /&gt;
: &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; macierz przejścia taka, że:&lt;br /&gt;
::&amp;lt;math&amp;gt;x(t) = A s(t)&amp;lt;/math&amp;gt; (*)&lt;br /&gt;
:&amp;lt;math&amp;gt;s(t) = A^{-1}x(t) = P x(t)&amp;lt;/math&amp;gt;&lt;br /&gt;
Macierz kowariancji dla sygnałów &amp;lt;math&amp;gt;x(t)&amp;lt;/math&amp;gt; estymujemy tak:&lt;br /&gt;
:&amp;lt;math&amp;gt; C_x = E[x(t)x(t)^T]&amp;lt;/math&amp;gt;&lt;br /&gt;
Podstawiając (*) mamy:&lt;br /&gt;
:&amp;lt;math&amp;gt; C_x = E[x x^T] = E[As(As)^T] = A E[s s^T] A^T = A C_s A^T&amp;lt;/math&amp;gt;&lt;br /&gt;
Z założenia, że źródła są niezależne wynika, że macierz &amp;lt;math&amp;gt;C_s&amp;lt;/math&amp;gt; jest diagonalna.&lt;br /&gt;
Przekształcając powyższe równanie możemy zapisać:&lt;br /&gt;
:&amp;lt;math&amp;gt;A^{-1} C_x (A^T)^{-1} = P C_x P^T = C_s&amp;lt;/math&amp;gt;&lt;br /&gt;
Odwzorowanie &amp;lt;math&amp;gt;P = A^{-1}&amp;lt;/math&amp;gt; diagonalizuje macierz &amp;lt;math&amp;gt;C_x&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Powyższe rozumowanie jest słuszne w przypadku gdy mamy do czynienia z sygnałem stacjonarnym, tzn. jego macierz kowariancji jest niezależna od czasu, czyli przez cały czas aktywna jest ta sama konfiguracja źródeł niezależnych.&lt;br /&gt;
W przypadku gdy tak nie jest to konstrukcję filtra przestrzennego można oprzeć o  jednoczesną diagonalizację macierzy kowariancji odpowiadających różnym stanom osoby badanej.&lt;br /&gt;
&lt;br /&gt;
[[Plik:Diagonalizacja.png|200px|center]]&lt;br /&gt;
&lt;br /&gt;
==Common Spatial Pattern ==&lt;br /&gt;
===Koncepcja===&lt;br /&gt;
Dla ustalenia uwagi możemy myśleć o eksperymencie wywołującym potencjał P300. Mamy w nim dwie sytuacje eksperymentalne. Oznaczmy (&amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - target) próby, w których pojawił się oczekiwany bodziec, zaś  (&amp;lt;math&amp;gt;NT&amp;lt;/math&amp;gt; - non-target) gdy pojawił się bodziec standardowy.&lt;br /&gt;
Chcielibyśmy znaleźć taki montaż, czyli taką kombinację liniową kanałów, które maksymalizuje stosunek mocy (wariancji) sygnałów rejestrowanych w dwóch rożnych warunkach eksperymentalnych. &lt;br /&gt;
&lt;br /&gt;
===Formalizm===&lt;br /&gt;
Metoda ta polega na znalezieniu takiego kierunku &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; w przestrzeni sygnałów, że sygnał z warunku &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; rzutowany na ten kierunek ma dużą wariancje a sygnał z warunku &amp;lt;math&amp;gt;NT&amp;lt;/math&amp;gt; ma wariancję małą. &lt;br /&gt;
&lt;br /&gt;
Rzutowanie sygnału &amp;lt;math&amp;gt;x(t)&amp;lt;/math&amp;gt; na kierunek &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; odbywa się przez policzenie iloczynu skalarnego dla każdej chwili czasu &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt; s_w(t) = w^T x(t)&amp;lt;/math&amp;gt;&lt;br /&gt;
Wariancja tego rzutowanego sygnału to:&lt;br /&gt;
:&amp;lt;math&amp;gt; \mathrm{var}(s_w) = E[s_w s_w^T] = E[ w^T x (w^T x)^T] = w^T E[x x^T] w = w^T C_x w &amp;lt;/math&amp;gt;&lt;br /&gt;
Zatem znalezienie właściwego kierunku rzutowania można wyrazić jako szukanie maksimum wyrażenia &amp;lt;math&amp;gt; J(w) &amp;lt;/math&amp;gt;(jest to tzw. iloraz Rayleigh'a):&lt;br /&gt;
: &amp;lt;math&amp;gt;J(w) = \frac{w^T C_T w}{w^T C_{NT} w}  &amp;lt;/math&amp;gt;&lt;br /&gt;
Ekstremum tego ilorazu można znaleźć poprzez policzenie gradientu &amp;lt;math&amp;gt;J(w)&amp;lt;/math&amp;gt; i przyrównanie go do zera:&lt;br /&gt;
:&amp;lt;math&amp;gt; \nabla J(w) =  \frac{ 1  C_{T} w+w^T C_{T} 1}{w^T C_{NT} w}-\frac{w^T  C_{T} w\left( 1  C_{NT} w+w^T C_{NT} 1\right)}{\left(w^T  C_{NT} w\right)^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
ponieważ macierze kowariancji są symetryczne &lt;br /&gt;
::&amp;lt;math&amp;gt;\nabla J(w) =   \frac{   1}{w^T  C_{NT} w}\left[    C_{T} w+ C_{T}w  -\frac{w^T  C_{T} w}{w^T  C_{NT} w} \left(   C_{NT} w+ C_{NT}w \right) \right]&amp;lt;/math&amp;gt;&lt;br /&gt;
::&amp;lt;math&amp;gt;= \frac{   2}{w^T  C_{NT} w}\left[     C_{T}w  -\frac{w^T  C_{T} w}{w^T  C_{NT} w}   C_{NT} w \right]&amp;lt;/math&amp;gt;&lt;br /&gt;
Przyrównując to wyrażenie do zera dostajemy:&lt;br /&gt;
:&amp;lt;math&amp;gt;       C_{T}w  =\frac{w^T  C_{T} w}{w^T  C_{NT} w}   C_{NT} w   &amp;lt;/math&amp;gt;&lt;br /&gt;
Liczba &amp;lt;math&amp;gt; \lambda =    \frac{w^T  C_{T} w}{w^T  C_{NT} w}   C_{NT} w &amp;lt;/math&amp;gt; jest uogólnioną wartością własną, zaś &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; jest uogólnionym wektorem własnym odpowiadającym tej wartości. &lt;br /&gt;
&lt;br /&gt;
Aby znaleźć &amp;lt;math&amp;gt; \lambda&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; wystarczy rozwiązać zagadnienie własne. W matlabie możemy w tym celu wykorzystać funkcję &amp;lt;tt&amp;gt;eig&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Odwzorowanie to można przedstawić w postaci macierzy &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;, której każdy wiersz zawiera wagi dla odpowiednich kanałów. &lt;br /&gt;
Macierz zawierająca sygnał &amp;lt;math&amp;gt;X^{\pm}(t)&amp;lt;/math&amp;gt; &lt;br /&gt;
ma wymiary &amp;lt;math&amp;gt;C \times  N&amp;lt;/math&amp;gt;, gdzie &lt;br /&gt;
&amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; to liczba kanałów EEG, natomiast &lt;br /&gt;
&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; to liczba próbek dla każdego z kanałów. &lt;br /&gt;
Macierz &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; przekształca sygnał &amp;lt;math&amp;gt;X^{\pm}(t)&amp;lt;/math&amp;gt;  zgodnie ze wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;X^{\pm}_{CSP}(t)=P^T  X^{\pm}(t) &amp;lt;/math&amp;gt;&lt;br /&gt;
Załóżmy dalej, że sygnały &amp;lt;math&amp;gt;X^{+}_{CSP} (t)&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;X^{-}_{CSP} (t)&amp;lt;/math&amp;gt; są generowane przez niezależne procesy stochastyczne, tzn. spełnione są następujące warunki. &lt;br /&gt;
# Syganły &amp;lt;math&amp;gt;X^{+}_{CSP} (t)&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;X^{-}_{CSP} (t)&amp;lt;/math&amp;gt; są niezależne.&lt;br /&gt;
# Brak korelacji pomiędzy kanałami w sygnałach&amp;lt;math&amp;gt;X^{+}_{CSP} (t)&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;X^{-}_{CSP} (t)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Przynajmniej dla jednego z kanałów wariancja przetransformowanego sygnału jest maksymalna przy wystąpieniu bodźca i minimalna przy jego braku.&lt;br /&gt;
Po przemnożeniu równania 2.3 przez &amp;lt;math&amp;gt;(X^{\pm}_{CSP} (t))^T&amp;lt;/math&amp;gt; otrzymamy macierz kowariancji przetransformowanych sygnałów uśrednioną po realizacjach:&lt;br /&gt;
:&amp;lt;math&amp;gt;R^{\pm}_{CSP} (t) = X^{\pm}_{CSP} (t)(X^{\pm}_{CSP} (t))^T = P^T X^{\pm} (t) (X^{\pm}(t))^T P = P^T R^{\pm}P&amp;lt;/math&amp;gt;  (2.4)&lt;br /&gt;
Gdzie &amp;lt;math&amp;gt;R^{\pm}&amp;lt;/math&amp;gt; to macierz kowariancji sygnału uśredniona po realizacjach. Z warunków 1 i 2 wynika, że macierze &amp;lt;math&amp;gt;R^{+}_{CSP}&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;R^{-}_{CSP}&amp;lt;/math&amp;gt; muszą być diagonalne, natomiast z warunku 3, że ich suma daje macierz jednostkową:&lt;br /&gt;
:&amp;lt;math&amp;gt;R^{+}_{CSP} + R^{-}_{CSP} = 1 &amp;lt;/math&amp;gt;  (2.5)&lt;br /&gt;
Tak więc suma par diagonalnych wartości (&amp;lt;math&amp;gt;k^{+}_{i}&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;k^{-}_{i}&amp;lt;/math&amp;gt;) w macierzach &amp;lt;math&amp;gt;R^{+}_{CSP}&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;R^{-}_{CSP}&amp;lt;/math&amp;gt; musi być równa 1.&lt;br /&gt;
Korzystając z równania 2.5 wartości na diagonali można również zapisać za pomocą wzoru:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;k^{+}_{i} = \vec{p}^{T}_{i} R^{+} \vec{p}_{i}    &amp;lt;/math&amp;gt; (2.6)&lt;br /&gt;
:&amp;lt;math&amp;gt;k^{-}_{i} = \vec{p}^T_{i} R^{-}\vec{p}_{i} &amp;lt;/math&amp;gt; (2.7)&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;\vec{p}_{i}&amp;lt;/math&amp;gt; to kolumnowy wektor macierzy &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Po przekształceniach ilorazu równań 2.6 i 2.7 można&lt;br /&gt;
otrzymać równanie:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;R^{+} \vec{p}_{i} = \frac{k^{+}_{i}}{k^{-}_{i}} R^{-} \vec{p}_{i} &amp;lt;/math&amp;gt;  (2.8)&lt;br /&gt;
￼&lt;br /&gt;
Równanie to przedstawia ogólną formę zagadnienia wartości własnych. Takie przedstawienie problemu umożliwia zastosowanie do jego rozwiązania wydajnych metod algebraicznych.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wektor własny &amp;lt;math&amp;gt;\vec{p}_i&amp;lt;/math&amp;gt; jest interpretowany jako filtr przestrzenny. Dzięki transformacie &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; sygnał zostaje przeniesiony do przestrzeni, dla której różnica wariancji dla poszczególnych klas jest największa. Zgodnie z równaniem 2.5 najbardziej różniące się od siebie kanały są skorelowane z największą wartością własną &amp;lt;math&amp;gt;k^{+}&amp;lt;/math&amp;gt;.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie symulacyjne ===&lt;br /&gt;
&amp;lt;source lang  = matlab&amp;gt;&lt;br /&gt;
% symulowany eksperyment składa się z sinusoidy udającej alfę spoczynkową i&lt;br /&gt;
% funkcji Gaussa udającego potencjał wywołany&lt;br /&gt;
% źródła te są symulowane niezależnie a potem mieszane przez macierz L&lt;br /&gt;
% symulujemy źródła&lt;br /&gt;
% s1 - symuluje alfę&lt;br /&gt;
% s2 - symuluje &amp;quot;potencjał wywołany&amp;quot; (ERP)&lt;br /&gt;
&lt;br /&gt;
%ustawiamy parametry do symulacji sygnałów&lt;br /&gt;
Fs = 100;&lt;br /&gt;
T = 1;&lt;br /&gt;
t = 0:1/Fs:T-1/Fs;&lt;br /&gt;
N_rep = 100;&lt;br /&gt;
N_chan = 2;&lt;br /&gt;
s = zeros(N_rep,N_chan, length(t));&lt;br /&gt;
X = zeros(N_rep,N_chan, length(t));&lt;br /&gt;
&lt;br /&gt;
% filtr przestrzenny - z takimi wagami trzeba wziąść kanały EEG aby odzyskać sygnały źródłowe&lt;br /&gt;
P = [1 2&lt;br /&gt;
    1.5 1.3]; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% topografie - z takimi wagami źródła dokładają się do poszczególnych elektrod&lt;br /&gt;
A = P^(-1); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
for r =1:N_rep % tworzymy kolejne realizacje &amp;quot;eksperymentu&amp;quot;&lt;br /&gt;
    s1 = sin(2*pi*11*t +pi/2+ 0*2*pi*rand())+ 0.02*randn(size(t));  % źródło alfa&lt;br /&gt;
    s2 = exp(-((t-0.8)/0.05).^2)+ 0.01*randn(size(t));              % źródło ERP&lt;br /&gt;
       &lt;br /&gt;
    s(r,1,:) = s1;&lt;br /&gt;
    s(r,2,:) = s2;&lt;br /&gt;
    tmp = squeeze(s(r,:,:));&lt;br /&gt;
    n = 0*randn(size(tmp));&lt;br /&gt;
    X(r,:,:) = A*tmp +n; % rzutujemy sygnały źródłowe na elektrody s -&amp;gt; x&lt;br /&gt;
    &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% wycinamy warunki &lt;br /&gt;
% baseline_ind   to indeksy pierwszej połowy każdego powtórzenia &amp;quot;baseline&amp;quot;&lt;br /&gt;
% ERP_ind        to indeksy drugiej połowy każdego powtórzenia zawierająca &amp;quot;ERP&amp;quot;&lt;br /&gt;
baseline_ind = find(t&amp;lt;0.5);&lt;br /&gt;
ERP_ind = find(t&amp;gt;=0.5);&lt;br /&gt;
&lt;br /&gt;
x_baseline_kan_1 = X(:,1,baseline_ind);&lt;br /&gt;
x_baseline_kan_2 = X(:,2,baseline_ind);&lt;br /&gt;
&lt;br /&gt;
x_ERP_kan_1 = X(:,1,ERP_ind);&lt;br /&gt;
x_ERP_kan_2 = X(:,2,ERP_ind);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% liczymy średnie macierze kowariancji:&lt;br /&gt;
R_E = zeros(N_chan,N_chan);&lt;br /&gt;
R_B = zeros(N_chan,N_chan);&lt;br /&gt;
for r =1:N_rep&lt;br /&gt;
    B = squeeze(X(r,:,baseline_ind)); &lt;br /&gt;
    R_B = R_B + B*B' ;&lt;br /&gt;
    &lt;br /&gt;
    E = squeeze(X(r,:,ERP_ind));&lt;br /&gt;
    R_E = R_E + E*E' ;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
R_B = R_B/N_rep;&lt;br /&gt;
R_E = R_E/N_rep;&lt;br /&gt;
&lt;br /&gt;
% rozwiązujemy uogólnione zagadnienie własne&lt;br /&gt;
[W,Lambda]=eig(R_E,R_B); % możliwa jest też optymalizacja wzg. średniej macierzy kowariancji (R_B+R_A)/2);&lt;br /&gt;
&lt;br /&gt;
% odzyskujemy sygnały źródeł&lt;br /&gt;
for r =1:N_rep&lt;br /&gt;
    S(r,:,:) = W'*squeeze(X(r,:,:));&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% pobieramy wycinki odpowiadające obu częściom eksperymentu z estymowanych&lt;br /&gt;
% źródeł&lt;br /&gt;
s_baseline_estymowany_kan1 = squeeze(  S(:,1,baseline_ind));&lt;br /&gt;
s_baseline_estymowany_kan2 = squeeze(  S(:,2,baseline_ind));&lt;br /&gt;
&lt;br /&gt;
s_ERP_estymowany_kan1 = squeeze(S(:,1,ERP_ind));&lt;br /&gt;
s_ERP_estymowany_kan2 = squeeze(S(:,2,ERP_ind));&lt;br /&gt;
&lt;br /&gt;
%%%%%%%%%%%%%% Ilustracje %%%%%%%%%%%%%%%%%%%%%%%&lt;br /&gt;
% ilustracja sygnałów mierzonych&lt;br /&gt;
figure(1);clf&lt;br /&gt;
subplot(2,2,1);&lt;br /&gt;
    plot(t(baseline_ind),(squeeze(X(:,1,baseline_ind)))','b'); hold on&lt;br /&gt;
    plot(t(ERP_ind),(squeeze(  X(:,1,ERP_ind)))','r'); hold off&lt;br /&gt;
    xlabel('elektroda 1')&lt;br /&gt;
    title('ilustracja sytuacji pomiarowej -\newline znane są potencjały na elektrodach w dwóch warunkach eksperymentalnych')&lt;br /&gt;
subplot(2,2,3);&lt;br /&gt;
    plot(t(baseline_ind),(squeeze(X(:,1,baseline_ind)))','b'); hold on&lt;br /&gt;
    plot(t(ERP_ind),(squeeze(  X(:,2,ERP_ind)))','r'); hold off&lt;br /&gt;
    xlabel('elektroda 2')&lt;br /&gt;
subplot(1,2,2)&lt;br /&gt;
    plot(x_baseline_kan_1(:),x_baseline_kan_2(:),'b.');&lt;br /&gt;
    hold on&lt;br /&gt;
    plot(x_ERP_kan_1(:),x_ERP_kan_2(:),'r.');&lt;br /&gt;
    xlim([-2,2])&lt;br /&gt;
    ylim([-2,2])&lt;br /&gt;
    axis equal&lt;br /&gt;
    &lt;br /&gt;
    % wektor własny odpowiadający największej wartości własnej jest&lt;br /&gt;
    % kierunkiem najbardziej różnicującym warunki eksperymentalne&lt;br /&gt;
    disp('wartości własne znajdują się na przekątnej macierzy Lambda')&lt;br /&gt;
    disp(Lambda)&lt;br /&gt;
    % rysujemy wersory jednostkowe w kierunkach wektorów własnych&lt;br /&gt;
    w1 = W(:,1); &lt;br /&gt;
    w1 = w1/norm(w1);&lt;br /&gt;
    w2 = W(:,2); &lt;br /&gt;
    w2 = w2/norm(w2);&lt;br /&gt;
    line([0, w1(1) ],[0,w1(2)],'Color',[0,0.3,0])&lt;br /&gt;
    text(w1(1),w1(2),'wektor własny 1')&lt;br /&gt;
    line([0, w2(1) ],[0,w2(2)],'Color',[1,0,1])&lt;br /&gt;
    text(w2(1),w2(2),'wektor własny 2')&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    xlabel('Amplituda na elektrodzie 1')&lt;br /&gt;
    ylabel('Amplituda na elektrodzie 2')   &lt;br /&gt;
    legend('baseline','ERP')&lt;br /&gt;
&lt;br /&gt;
% Ilustracja estymowanych źródeł&lt;br /&gt;
figure(2);clf&lt;br /&gt;
subplot(2,2,1);&lt;br /&gt;
    plot(t(baseline_ind),(squeeze(S(:,1,baseline_ind)))','b');hold on&lt;br /&gt;
    plot(t(ERP_ind),(squeeze(S(:,1,ERP_ind)))','r');hold off&lt;br /&gt;
    xlabel('estymowane zrodlo  1')&lt;br /&gt;
    title('ilustracja estymacji -\newline estymowane są potencjały źródeł w dwóch warunkach eksperymentalnych')    &lt;br /&gt;
subplot(2,2,3);&lt;br /&gt;
    plot(t(baseline_ind),(squeeze(S(:,2,baseline_ind)))','b');hold on&lt;br /&gt;
    plot(t(ERP_ind),(squeeze(S(:,2,ERP_ind)))','r');hold off&lt;br /&gt;
    xlabel('estymowane zrodlo  2');&lt;br /&gt;
subplot(1,2,2)&lt;br /&gt;
    plot(s_baseline_estymowany_kan1(:),s_baseline_estymowany_kan2(:),'b.');&lt;br /&gt;
    hold on&lt;br /&gt;
    plot(s_ERP_estymowany_kan1(:),s_ERP_estymowany_kan2(:),'r.');   &lt;br /&gt;
    &lt;br /&gt;
    xlabel('Amplituda estym. źródła 1')&lt;br /&gt;
    ylabel('Amplituda estym. źródła 2')   &lt;br /&gt;
    legend('baseline','ERP')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Zastosowanie filtra CSP do detekcji potencjału P300==&lt;br /&gt;
===Eksperyment===&lt;br /&gt;
====Przygotowanie do badania:====&lt;br /&gt;
* założyć czepek z elektrodami w systemie 10-20;&lt;br /&gt;
* elektrody referencyjne: M1 i M2;&lt;br /&gt;
* elektroda GND w pozycji AFz.&lt;br /&gt;
&lt;br /&gt;
====Przygotowanie scenariuszy obci ====&lt;br /&gt;
* w terminalu uruchomić &amp;lt;tt&amp;gt;obci srv&amp;lt;/tt&amp;gt;;&lt;br /&gt;
* w terminalu uruchomić &amp;lt;tt&amp;gt;obci_gui --preset brain2013&amp;lt;/tt&amp;gt;;&lt;br /&gt;
* w interfejsie GUI zapisujemy scenariusze do własnego katalogu np &amp;amp;bdquo;P300&amp;amp;rdquo;&lt;br /&gt;
** &amp;amp;bdquo;P-Brain2013 Signal (with ID)&amp;amp;rdquo; jako np. &amp;amp;bdquo;Sygnal&amp;amp;rdquo;&lt;br /&gt;
** &amp;amp;bdquo;P-Brain2013 Calibration p300&amp;amp;rdquo; jako &amp;amp;bdquo;kalibracjaP300&amp;amp;rdquo;&lt;br /&gt;
** &amp;amp;bdquo;P-Brain 2013 p300&amp;amp;rdquo; jako &amp;amp;bdquo;Labirynt&amp;amp;rdquo;&lt;br /&gt;
* w przeglądarce plików otwórz katalog ~/.obci/scenarios/P300. Powinien on zawierać pliki: Sygnal.ini, kalibracjaP300.ini, Labirynt.ini oraz katalogi  Sygnal_configs, kalibracjaP300_configs, Labirynt_configs.&lt;br /&gt;
*  edytujemy parametry peerów.&lt;br /&gt;
** z katalogu ~/.obci/scenarios/P300/Sygnal_configs kopiujemy plik amplifier.ini do katalogu ~/.obci/scenarios/P300 jako global_amplifier.ini. To pozwoli nam zmieniać ustawienia wzmacniacza dla wszystkich scenariuszy jednocześnie.&lt;br /&gt;
** w naszych scenariuszach zapisanych w plikach Sygnal.ini, kalibracjaP300.ini, Labirynt.ini podmieniamy ścieżkę &amp;lt;tt&amp;gt;config =&amp;lt;/tt&amp;gt; w sekcji &amp;lt;tt&amp;gt;[peers.amplifier]&amp;lt;/tt&amp;gt; tak, aby pokazywała na ten skopiowany plik global_amplifier.ini&lt;br /&gt;
** w tym pliku global_amplifier.ini podmieniamy linijki (tak aby były to listy faktycznie wykorzystywanych kanałów) z:&lt;br /&gt;
*** &amp;lt;tt&amp;gt;active_channels&amp;lt;/tt&amp;gt;&lt;br /&gt;
*** &amp;lt;tt&amp;gt;channel_names&amp;lt;/tt&amp;gt;&lt;br /&gt;
** dodajemy też linijkę: &amp;lt;tt&amp;gt;sampling_rate = 256&amp;lt;/tt&amp;gt;&lt;br /&gt;
* wchodzimy po kolei do katalogów: Sygnal_configs, kalibracjaP300_configs, Labirynt_configs i odnajdujemy plik switch_backup.ini. W tym pliku ustawiamy parametr &amp;lt;tt&amp;gt;new_scenario&amp;lt;/tt&amp;gt; na pusty. To spowoduje, że scenariusze te nie będą uruchamiać kolejnych scenariuszy po zakończeniu działania.&lt;br /&gt;
** edytujemy plik ~/.obci/scenarios/P300/kalibracjaP300_configs/clasifier.ini &lt;br /&gt;
*** zmieniamy linię&lt;br /&gt;
::: &amp;lt;tt&amp;gt;ignore_channels = DriverSaw;AmpSaw;PO7;PO8&amp;lt;/tt&amp;gt;&lt;br /&gt;
::: na &lt;br /&gt;
::: &amp;lt;tt&amp;gt;ignore_channels = DriverSaw;AmpSaw;A1;A2&amp;lt;/tt&amp;gt;&lt;br /&gt;
::* oraz linię:&lt;br /&gt;
::: &amp;lt;tt&amp;gt;montage_channels = PO7;PO8&amp;lt;/tt&amp;gt;&lt;br /&gt;
::: na &lt;br /&gt;
::: &amp;lt;tt&amp;gt;montage_channels = A1;A2&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Przeprowadzenie badania:====&lt;br /&gt;
# Uruchom scenariusz &amp;amp;bdquo;Sygnał&amp;amp;rdquo;.&lt;br /&gt;
# Tworzy on w katalogu domowym plik o nazwie &amp;lt;tt&amp;gt;file_id_name&amp;lt;/tt&amp;gt;.&lt;br /&gt;
# Uruchamiamy Svaroga z terminala poleceniem &amp;lt;tt&amp;gt;svarog&amp;lt;/tt&amp;gt;. W zakładce sygnały on-line odnajdujemy nazwę naszego scenariusza &amp;amp;bdquo;Sygnal&amp;amp;rdquo;. Podłączamy się do niego i poprawiamy ewentualnie źle kontaktujące elektrody.&lt;br /&gt;
# Jak już jesteśmy zadowoleni z jakości sygnału to zatrzymujemy scenariusz &amp;amp;bdquo;Sygnal&amp;amp;rdquo; w obci.&lt;br /&gt;
# W pliku &amp;lt;tt&amp;gt;file_id_name&amp;lt;/tt&amp;gt;  znajduje się string, który stanowi rdzeń do tworzenia nazw plików, z których korzystają nasze scenariusze. Proszę zmienić ten string np. na: &amp;lt;tt&amp;gt;test1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
# Uruchamiamy scenariusz &amp;amp;bdquo;kalibracjaP300&amp;amp;rdquo;. Badany będzie oglądał interfejs z trzema literami A B C migającymi w losowej kolejności. Zadaniem jest zliczanie mignięć litery B.&lt;br /&gt;
# Po zakończeniu kalibracji uruchamiamy scenariusz &amp;amp;bdquo;Labirynt&amp;amp;rdquo;.&lt;br /&gt;
# Danych z kalibracji potrzebować będziemy kilka zestawów.  Proszę powtórzyć kilkukrotnie scenariusz &amp;amp;bdquo;kalibracjaP300&amp;amp;rdquo;. Przed każdym uruchomieniem trzeba zmienić string w pliku &amp;lt;tt&amp;gt;file_id_name&amp;lt;/tt&amp;gt; np. na &amp;lt;tt&amp;gt;test???&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;???&amp;lt;/tt&amp;gt; oznacza kolejne numery.&lt;br /&gt;
&lt;br /&gt;
===Analiza wstępna===&lt;br /&gt;
* Wczytać dane kalibracyjne do Matlaba i pociąć je na realizacje typu T &amp;amp;mdash; &amp;amp;bdquo;target&amp;amp;rdquo; (związane z wystąpieniami litery &amp;amp;bdquo;B&amp;amp;rdquo;) i NT &amp;amp;mdash; &amp;amp;bdquo;non-target&amp;amp;rdquo; (pozostałe litery) o długości &amp;amp;minus;200 do +800 ms wokół triggerów. Dla każdej realizacji odjąć trend liniowy.&lt;br /&gt;
* Sygnał zmontować wzgl. &amp;amp;bdquo;połączonych uszu&amp;amp;rdquo; i wyświetlić średnie przebiegi dla warunku T i NT w układzie topograficznym &amp;amp;mdash; wykorzystać w tym celu funkcję &amp;lt;tt&amp;gt;topoplot&amp;lt;/tt&amp;gt; z pakietu Eeglab.&lt;br /&gt;
&lt;br /&gt;
Poniżej zaprezentowany jest przykładowy skrypt do cięcia danych wokół znaczników. Działa on z plikami zawartymi w archiwum:&lt;br /&gt;
: [[Plik:KalibracjaP300.tar.gz]] &lt;br /&gt;
Korzysta z funkcji pomocniczych dostępnych w dystrybucji obci w katalogu &lt;br /&gt;
: /usr/share/openbci/analysis/matlab_obci_signal_processing&lt;br /&gt;
Openbci można pobrać z https://github.com/BrainTech/openbci&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = matlab&amp;gt;&lt;br /&gt;
% ustalamy nzawy plików z danymi&lt;br /&gt;
nazwaPliku = 'p_6301423_calibration_p300.obci';&lt;br /&gt;
nameOfXMLFile = strcat(nazwaPliku,'.xml');&lt;br /&gt;
nameOfTagFile = strcat(nazwaPliku,'.tag'); %tagi = znaczniki zdarzeń&lt;br /&gt;
namesOfDataFiles = strcat(nazwaPliku,'.raw');&lt;br /&gt;
&lt;br /&gt;
% inicjujemy obiekt rm&lt;br /&gt;
rm = ReadManager(nameOfXMLFile,namesOfDataFiles,nameOfTagFile);&lt;br /&gt;
&lt;br /&gt;
% obieramy przydatne parametry i znaczniki&lt;br /&gt;
numberOfChannels  = rm.get_param('number_of_channels');&lt;br /&gt;
namesOfChannels   = rm.get_param('channels_names');&lt;br /&gt;
samplingFrequency = rm.get_param('sampling_frequency');&lt;br /&gt;
tagsStruct        = rm.get_tags();&lt;br /&gt;
&lt;br /&gt;
% tworzenie list znaczników Target i NonTarget&lt;br /&gt;
numberOfStruct = length(tagsStruct);&lt;br /&gt;
targetTimeStamps = [];&lt;br /&gt;
NonTargetTimeStamps = [];&lt;br /&gt;
for structNumber = 1:numberOfStruct % iterujemy się przez tagi&lt;br /&gt;
    if(strcmp(tagsStruct(structNumber).name,'blink')) % szukamy tagów o nazwie 'blink'&lt;br /&gt;
        index = tagsStruct(structNumber).children.index; % tu jest numer pola stymulacji&lt;br /&gt;
        target= tagsStruct(structNumber).children.target;% tu jest numer pola na którym wyświetlany jest target&lt;br /&gt;
        if index == target % warunek na to, że mamy do czynienia z tagiem target&lt;br /&gt;
            targetTimeStamps = [targetTimeStamps tagsStruct(structNumber).start_timestamp]; %dodajemy timeStamp do listy targetów&lt;br /&gt;
        else&lt;br /&gt;
            NonTargetTimeStamps = [NonTargetTimeStamps tagsStruct(structNumber).start_timestamp];%dodajemy timeStamp do listy non-targetów&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
% pobieramy próbki&lt;br /&gt;
samples = double(rm.get_samples()); % konwersja na double jest potrzebna żeby dobrze funkcjonowało filtrowanie&lt;br /&gt;
samples=samples(1:8,:); % odrzucamy kanały, które nie mają EEG&lt;br /&gt;
numberOfChannels =8;&lt;br /&gt;
&lt;br /&gt;
% filtrujemy dolnoprzepustowo aby odrzucić artefakty sieci i część&lt;br /&gt;
% artefaktów mięśniowych&lt;br /&gt;
[b,a] = cheby2(6,80,25 /(samplingFrequency/2),'low');&lt;br /&gt;
for ch = 1:numberOfChannels&lt;br /&gt;
    samples(ch,:)=filtfilt(b,a,samples(ch,:));&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% montujemy dane do wspólnej średniej (common average)&lt;br /&gt;
M = -ones(8,8)/8;&lt;br /&gt;
M=M+eye(8,8)*9/8;&lt;br /&gt;
samples = 0.0715*M*samples;&lt;br /&gt;
&lt;br /&gt;
% wycinamy dane wokół znaczników&lt;br /&gt;
PRE = -0.2; % czas przed tagiem w sek.&lt;br /&gt;
POST = 0.8; % czas po tagu w sek.&lt;br /&gt;
wycinek = floor(PRE*samplingFrequency:POST*samplingFrequency); % tablica ze &amp;quot;standardowymi&amp;quot; indeksami do cięcia&lt;br /&gt;
&lt;br /&gt;
% pobieramy targety&lt;br /&gt;
TargetSignal = zeros(length(targetTimeStamps),numberOfChannels, length(wycinek)); % tablica na sygnały target&lt;br /&gt;
for trialNumber = 1:length(targetTimeStamps)&lt;br /&gt;
    trigerOnset = floor(targetTimeStamps(trialNumber)*samplingFrequency);&lt;br /&gt;
    tenWycinek = wycinek + trigerOnset;&lt;br /&gt;
    if tenWycinek(1)&amp;gt;0 &amp;amp;&amp;amp; tenWycinek(end)&amp;lt;=size(samples,2) % test czy wycinek który chcemy pobrać nie wystaje poza dostępny sygnał&lt;br /&gt;
        tmpSignal = samples(:,tenWycinek);&lt;br /&gt;
        tmpSignal = detrend(tmpSignal')'; % usuwanie liniowego trendu - przy krótkich wycinkach działa lepiej niż filtrowanie górnoprzepustowe&lt;br /&gt;
        TargetSignal(trialNumber, :,:) = tmpSignal;&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
% pobieramy non-targety&lt;br /&gt;
NonTargetSignal = zeros(length(NonTargetTimeStamps),numberOfChannels, length(wycinek));% tablica na sygnały non-target&lt;br /&gt;
for trialNumber = 1:length(NonTargetTimeStamps)&lt;br /&gt;
    trigerOnset = floor(NonTargetTimeStamps(trialNumber)*samplingFrequency);&lt;br /&gt;
    tenWycinek = wycinek + trigerOnset;&lt;br /&gt;
    if tenWycinek(1)&amp;gt;0 &amp;amp;&amp;amp; tenWycinek(end)&amp;lt;=size(samples,2)&lt;br /&gt;
        tmpSignal = samples(:,tenWycinek);&lt;br /&gt;
        tmpSignal = detrend(tmpSignal')';&lt;br /&gt;
        NonTargetSignal(trialNumber, :,:) = tmpSignal;&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
%&lt;br /&gt;
% dla ilustracji podglądamy średnie po powtórzeniach ze wszystkich targetów&lt;br /&gt;
% i non-targetów&lt;br /&gt;
plot(squeeze(mean(TargetSignal,1))','r');&lt;br /&gt;
hold on&lt;br /&gt;
plot(squeeze(mean(NonTargetSignal,1))','b')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Analiza CSP===&lt;br /&gt;
* Korzystając z danych kalibracyjnych wykonać analizę CSP wzmacniającą potencjał P300.&lt;br /&gt;
* Zaprezentować średnią ze wszystkich kanałów źródłowych z warunku target (jeden kolor) i non-target (inny kolor) w subplotach ułożonych w prostokątnej siatce. Zaobserwować dla którego kanału średnie różnią się najbardziej. Czy jest związek tego kanału z wartościami własnymi?&lt;br /&gt;
&lt;br /&gt;
* Dla kanału najbardziej różnicującego wykonać mapki topograficzne wektorów odpowiadających:&lt;br /&gt;
** filtrowi przestrzennemu &lt;br /&gt;
** rzutu topograficznego źródła na elektrody.&lt;br /&gt;
* Do wykonania tych mapek wykorzystać funkcję &amp;lt;tt&amp;gt;topoplot&amp;lt;/tt&amp;gt; z pakietu &amp;lt;tt&amp;gt;eeglab&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Zbadać powtarzalność topografii pomiędzy plikami konfiguracyjnymi.&lt;br /&gt;
&lt;br /&gt;
===Wybór i separacja cech===&lt;br /&gt;
* Przedstaw na rysunkach nałożone na siebie pojedyncze realizacje z warunków target i non-target po rzutowaniu na wektor &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; odpowiadający największej i kolejnej wartości  własnej. &lt;br /&gt;
* Przedstaw wykresy punktowe, takie że na jednej osi jest moc sygnału odpowiadającego największej wartości własnej a na drugiej osi kolejnej wartości własnej; jeden punkt reprezentuje jedno powtórzenie.&lt;br /&gt;
* Wykonaj serię wykresów jak w poprzednim punkcie dla uśrednień kolejno po 2, 4, 6, 8 i 10 realizacjach. Zaobserwuj jak zmienia się separacja w grupach target i non-target.&lt;br /&gt;
&lt;br /&gt;
==Filtry przestrzenne dla SSEP ==&lt;br /&gt;
&lt;br /&gt;
=== Teoria===&lt;br /&gt;
Ciekawa koncepcja filtra przestrzennego dla SSVEP zaprezentowana jest  tu: http://www.eurasip.org/Proceedings/Eusipco/Eusipco2009/contents/papers/1569193209.pdf&lt;br /&gt;
&lt;br /&gt;
Po krótce można ją rozumieć podobnie do tego co robiliśmy rozważając filtry przestrzenne CSP, z tym, że dla SSVEP oraz innych potencjałów wywołanych stanu ustalonego możemy skorzystać z dodatkowych informacji dotyczących poszukiwanych źródeł. Wiemy mianowicie, że powinny one oscylować z częstością bodźca, i być może jej harmonicznych.&lt;br /&gt;
&lt;br /&gt;
Przyda nam się macierz &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; zbudowana tak, że w kolejnych kolumnach znajdują się sinusy i cosinusy kolejnych częstości harmonicznych. Wektory te unormujemy, żeby miały energię równą 1. Innymi słowy macierz &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; zbudowana jest z wersorów rozpinających przestrzeń, w której powinien znajdować się sygnał SSVEP.&lt;br /&gt;
&lt;br /&gt;
W matlabie możemy taką macierz zbudować tak:&lt;br /&gt;
&amp;lt;source lang = matlab&amp;gt;&lt;br /&gt;
% Fs - częstość próbkowania&lt;br /&gt;
% numberOfSamples - długość sygnału w próbkach&lt;br /&gt;
% numberOfHarmonics - liczba harmonicznych, które chcemy włączyć do analizy&lt;br /&gt;
t = (0:1:numberOfSamples - 1)/Fs; &lt;br /&gt;
S = zeros(numberOfSamples, 2*numberOfHarmonics);&lt;br /&gt;
&lt;br /&gt;
for harmonicNumber = 1:numberOfHarmonics&lt;br /&gt;
    c = cos(2*pi*stimulationFrequency*harmonicNumber*t);&lt;br /&gt;
    s = sin(2*pi*stimulationFrequency*harmonicNumber*t);&lt;br /&gt;
    S(:,(harmonicNumber - 1)*2 + 1) = c/norm(c);&lt;br /&gt;
    S(:,(harmonicNumber - 1)*2 + 2) = s/norm(s);&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aby w badanym sygnale znaleźć składowe odpowiadające SSVEP musimy rzutować sygnał &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; (macierz sygnałów ''kanały x próbki'')  na przestrzeń rozpiętą przez &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;A = X*S&amp;lt;/math&amp;gt;&lt;br /&gt;
Macierz &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; zawiera współczynniki będące iloczynami skalarnymi sygnałów i wersorów. Mówią one o tym &amp;quot;jak duże&amp;quot; jest sinusa bądź cosinusa o danej częstości w pierwotnym sygnale. Komponenty SSVEP zawarte w sygnale &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; odzyskujemy tak:&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathrm{SSVEP} = A S^T&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Modelujemy rejestrowany sygnał jako:&lt;br /&gt;
:&amp;lt;math&amp;gt;X = \mathrm{SSVEP} + Y &amp;lt;/math&amp;gt;&lt;br /&gt;
gdzie: &lt;br /&gt;
:&amp;lt;math&amp;gt;Y = X-\mathrm{SSVEP}&amp;lt;/math&amp;gt; &lt;br /&gt;
: to wszystkie komponenty sygnału, które nas nie interesują.&lt;br /&gt;
&lt;br /&gt;
Filtr przestrzenny, który chcemy zbudować powinien maksymalizować stosunek wariancji &amp;lt;math&amp;gt;\mathrm{SSVEP} = A S^T&amp;lt;/math&amp;gt; do wariancji &amp;lt;math&amp;gt;Y = X-\mathrm{SSVEP}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Dalej możemy zastosować technikę znaną z konstrukcji filtrów CSP, tzn. maksymalizacji ilorazu Rayleigh'a za pomocą rozwiązania ogólnionego zagadnienia własnego dla macierzy kowariancji &amp;lt;math&amp;gt;\mathrm{SSVEP} &amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;Y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Poniżej prosta demonstracja dla danych zebranych EEG przy stymulacji SSVEP z częstotliwością 38Hz.===&lt;br /&gt;
Spakowane dane: [[Plik:PrzykladoweDaneSSVEP.mat.gz]].&lt;br /&gt;
W oparciu o powyższy opis proszę zaimplementować  funkcję &amp;lt;tt&amp;gt;cosSinCSP&amp;lt;/tt&amp;gt;. Prawidłowo zaimplementowana funkcja wraz z poniższym kodem powinna generować rysunek:&lt;br /&gt;
[[Plik:Rys_SSVEP_demo.png|400px|thumb|right|podpis grafiki]] &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = matlab&amp;gt;&lt;br /&gt;
% wczytujemy dane&lt;br /&gt;
load('PrzykladoweDaneSSVEP.mat');&lt;br /&gt;
&lt;br /&gt;
[numberOfTrials numberOfChannels numberOfSamples] = size(X.data);&lt;br /&gt;
namesOfChannels = X.channels;&lt;br /&gt;
 &lt;br /&gt;
% numberOfChannels numberOfSamples numberOfTrials&lt;br /&gt;
P = zeros(numberOfChannels,numberOfChannels);&lt;br /&gt;
numberOfHarmonics = 3;&lt;br /&gt;
signal = X.data; % (  powtórzenie,  kanał, próbki)&lt;br /&gt;
 &lt;br /&gt;
S = zeros(size(signal));&lt;br /&gt;
P = cosSinCSP(signal,X.stimulation,numberOfHarmonics,X.sampling);&lt;br /&gt;
for powt = 1:size(signal,1)&lt;br /&gt;
    S(powt,:,:) = P'*squeeze(signal(powt,:,:));&lt;br /&gt;
end&lt;br /&gt;
 &lt;br /&gt;
figure('Name',['Stymulacja: ',num2str(X.stimulation),' Hz'])&lt;br /&gt;
for i =1:numberOfChannels&lt;br /&gt;
    % rysujemy widma uśrednione po realizacjach dla danych &lt;br /&gt;
    % z oryginalnych kanałów EEG&lt;br /&gt;
    subplot(2,8,i)&lt;br /&gt;
    PP=0;&lt;br /&gt;
    for rep = 1:numberOfTrials&lt;br /&gt;
        x = signal(rep,i,:);&lt;br /&gt;
        [Pxx,ff] = pwelch(x, X.sampling, 1, X.sampling, X.sampling);&lt;br /&gt;
        PP =PP + Pxx;&lt;br /&gt;
    end&lt;br /&gt;
    plot(ff(ff&amp;lt;60),PP(ff&amp;lt;60))&lt;br /&gt;
    title(namesOfChannels{i})&lt;br /&gt;
 &lt;br /&gt;
    % rysujemy widma uśrednione po realizacjach dla danych &lt;br /&gt;
    % z estymowanych źródeł CSP&lt;br /&gt;
    subplot(2,8,8+i)&lt;br /&gt;
    PP=0;&lt;br /&gt;
    for rep = 1:numberOfTrials&lt;br /&gt;
        s = S(rep,i,:);&lt;br /&gt;
        [Pss,ff]=pwelch(s, X.sampling, 1, X.sampling, X.sampling);&lt;br /&gt;
        PP =PP + Pss;&lt;br /&gt;
    end&lt;br /&gt;
    plot(ff(ff&amp;lt;60),PP(ff&amp;lt;60))&lt;br /&gt;
    title(['źródło CSP: ', num2str(i)])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przykładowy skrypt i dane prezentujący konstrukcję i działanie tego typu filtrów przestrzennych dla pełnych danych z eksperymentu SSVEP: [[Plik:SSVEP_demo_csp.tar.gz]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===Eksperyment ASSR===&lt;br /&gt;
W eksprymencie wykorzystujemy układ do generacji potencjałów słuchowych stanu ustalonego (ASSR). Wejście układu ASSR typu mini-jack wkładamy w wyjście słuchawkowe w laptopie. Drugie wejście układu ASSR wkładamy do wyjścia triggera we wzmacniaczu. Uruchamiamy plik dźwiękowy MM40tr.wav. Można go znalezc w: http://www.fuw.edu.pl/~suffa/LabEEG/MM40tr.wav&lt;br /&gt;
&lt;br /&gt;
Stymulacja dźwiękowa składa sie z fali nośnej o częstości 400 Hz modulowanej z częstością 40 Hz. Plik dźwiękowy zawiera 5 sekund ciszy i 5 sekund stymulacji, powtórzone 40 razy.&lt;br /&gt;
&lt;br /&gt;
====Rejestracja sygnału====&lt;br /&gt;
# Zakładamy czepek i elektrody w systemie 10-10, dbamy o to by opory pomiędzy elektrodami były poniżej 5 k&amp;amp;Omega; i różnice pomiędzy oporami różnych elektrod nie przekraczały 20%.&lt;br /&gt;
# Oklejamy kwadrat 3&amp;amp;times;3 elektrod na korze słuchowej z lewej strony (elektrody FT7, FC5, FC3, T7, C5, T3, TP7, CP5, CP3), 3&amp;amp;times;3 elektrod na korze słuchowej z prawej strony (elektrody FT8, FC6, FC4, T8, C6, T4, TP8, CP6, CP4), elektrody Fz, Cz, Pz i Oz, elektrody referencyjne A1 i A2. W sumie powinno być 24 elektrody.&lt;br /&gt;
# Elektrodę GND mocujemy na pozycji AFz.&lt;br /&gt;
# Sygnał rejestrujemy z częstością 2048 Hz.&lt;br /&gt;
# Do rejestracji stosujemy scenariusz 'ASSR' w interfejsie obci_gui.&lt;br /&gt;
&lt;br /&gt;
====Analiza====&lt;br /&gt;
 JZ: zmieniłbym analizę na czas-częstość i zrobił porównanie montażu usznego do filtra G.G. Moliny&lt;br /&gt;
&lt;br /&gt;
Początek stymulacji dźwiękowej oznaczymy jako 0. Poniższą analizę zastosuj dla sygnałów w referencji do uśrednionych odprowadzeń usznych A1 i A2.&lt;br /&gt;
Wyznaczenie pasma częstości odpowiedzi ASSR&lt;br /&gt;
# Z sygnału wycinamy fragmenty od 0 do 5 sek. dla wszystkich elektrod położone nad korą słuchową.&lt;br /&gt;
# Dla każdej realizacji obliczamy widma metodą Welcha.&lt;br /&gt;
# Otrzymane zespolone widma uśredniamy po realizacjach.&lt;br /&gt;
# Sprawdzamy czy w uśrednionym widmie występuję maksimum w częstości modulacji tj. 40 Hz.&lt;br /&gt;
&lt;br /&gt;
====Wyznaczenie przebiegu czasowego ERD i ERS====&lt;br /&gt;
# Zaprojektuj filtry pasmowo przepustowe (Czebyszewa 2 rodzaju) zgodne z wyznaczonym pasmem. Zbadaj funkcje przenoszenia i odpowiedzi impulsowej.&lt;br /&gt;
# Powycinaj sygnały od &amp;amp;minus;5 do +10 sekund (wszystkie kanały). Przefiltruj każdą realizację.&lt;br /&gt;
# Oblicz moc chwilową za pomocą transformaty Hilberta (kwadrat modułu transformaty Hilberta).&lt;br /&gt;
# Uśrednij moc chwilową po realizacjach.&lt;br /&gt;
# Oblicz względną zmianę mocy chwilowej względem czasu &amp;amp;minus;4 do &amp;amp;minus;2 s. W ten sposób otrzymasz przebieg ERD i ERS w czasie.&lt;br /&gt;
# Wykreśl ERD i ERS w układzie topograficznym. (Rozmieść subploty tak, aby z w przybliżeniu odpowiadały pozycjom elektrod).&lt;br /&gt;
&lt;br /&gt;
====Transformacja Hjortha====&lt;br /&gt;
Transformacja Hjortha jest przybliżeniem numerycznym transformacji Laplace'a, czyli drugiej pochodnej przestrzennej. Obliczamy ją jako różnicę potencjału pomiędzy daną elektrodą i średnią z czterech sąsiednich elektrod.&lt;br /&gt;
Przelicz potencjały z elektrod, w których występuję odpowiedź ASSR na montaż Hjortha i powtórz analizę ERD/ERS opisaną powyżej.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==ICA jako filtr przestrzenny==&lt;br /&gt;
===Definicja ===&lt;br /&gt;
Independent Component Analysis (ICA) jest metodą statystycznej analizy sygnałów, która dokonuje dekompozycji wielokanałowych zapisów na składowe niezależne w sensie statystycznym.&lt;br /&gt;
Dwie składowe &amp;lt;math&amp;gt;s_{1}&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;s_{2}&amp;lt;/math&amp;gt; są niezależne jeżeli wiedza o wartości &amp;lt;math&amp;gt;s_{1}&amp;lt;/math&amp;gt; nie daje żadnych informacji o możliwych wartościach &amp;lt;math&amp;gt;s_{2}&amp;lt;/math&amp;gt;. ICA może być wyrażona przez prosty model generatywny:&lt;br /&gt;
: &amp;lt;math&amp;gt; \mathbf{x} = \mathbf{D}\mathbf{s} &amp;lt;/math&amp;gt;&lt;br /&gt;
: gdzie &amp;lt;math&amp;gt;\mathbf{x}=\{x^{1},x^{2},\dots, x^{n}\}&amp;lt;/math&amp;gt; jest zmierzonym &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; kanałowym sygnałem, &amp;lt;math&amp;gt;\mathbf{D}&amp;lt;/math&amp;gt; jest macierzą mieszającą zaś &amp;lt;math&amp;gt;\mathbf{s}=\{s^{1},s^{2},\dots,s^{n} \}&amp;lt;/math&amp;gt; jest aktywnością  &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; źródeł. Podstawowym założeniem dotyczącym &amp;lt;math&amp;gt;\mathbf{s}&amp;lt;/math&amp;gt; jest to, że &amp;lt;math&amp;gt;s^{i}&amp;lt;/math&amp;gt; są statystycznie niezależne.  Aby wyestymować model musimy też założyć, że składowe mają niegaussowskie rozkłady wartości (Hyvarinen, 2000).&lt;br /&gt;
&lt;br /&gt;
Dodatkowo model ten zakłada następujące fakty:&lt;br /&gt;
# Sygnał jest liniową mieszaniną aktywności źródeł&lt;br /&gt;
# Sygnały pochodzące z każdego ze źródeł są niezależne od pozostałych&lt;br /&gt;
# Źródła oraz proces ich mieszania są stacjonarne, tzn, ich momenty statystyczne nie zależą od czasu&lt;br /&gt;
# Energie (wariancje) źródeł nie mogą być wyznaczone jednoznacznie. Dzieje się tak ponieważ pomnożenie amplitudy &amp;lt;math&amp;gt;i-{tego}&amp;lt;/math&amp;gt; źródła może być uzyskane poprzez przemnożenie albo &amp;lt;math&amp;gt;s^{i}&amp;lt;/math&amp;gt; albo przez przemnożenie  &amp;lt;math&amp;gt;i-tej&amp;lt;/math&amp;gt; kolumny macierzy &amp;lt;math&amp;gt;\mathbf{D}&amp;lt;/math&amp;gt;}.  Naturalnym rozwiązaniem tej niejednoznaczności jest wprowadzenie konwencji, że komponenty są normowane tak aby miały wariancję 1: &amp;lt;math&amp;gt;E[s^{i}]=1&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Kolejność komponentów jest dowolna.  Bo jeśli: w ten sam sposób zmienimy kolejność komponentów w &amp;lt;math&amp;gt;\mathbf{s}&amp;lt;/math&amp;gt;, i kolumn w &amp;lt;math&amp;gt;\mathbf{D}&amp;lt;/math&amp;gt; to dostaniemy dokładnie ten sam sygnał &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Głównym wyzwaniem w analizie ICA jest estymacja macierzy mieszającej &amp;lt;math&amp;gt;\mathbf{D}&amp;lt;/math&amp;gt;. Gdy jest ona znana to komponenty mogą być wyliczone w następujący sposób:&lt;br /&gt;
: &amp;lt;math&amp;gt; \mathbf{s} = \mathbf{D}^{-1}\mathbf{x} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Estymacja ===&lt;br /&gt;
Znalezienie niezależnych komponentów może być rozważane w świetle Centralnego Twierdzenia Granicznego jako poszukiwanie komponentów o możliwie nie gaussowskim rozkładzie.&lt;br /&gt;
Aby zrozumieć to podejście prześledźmy heurystykę zaproponowaną przez (Hyvarinen, 2000). &lt;br /&gt;
Dla prostoty załóżmy, że poszukiwane źródła niezależne mają identyczne rozkłady. &lt;br /&gt;
Zdefiniujmy &amp;lt;math&amp;gt;y = \mathbf{w}^{\mathsf{T}}\mathbf{x}&amp;lt;/math&amp;gt;. Zauważmy, że jeśli &amp;lt;math&amp;gt;\mathbf{w}^{\mathsf{T}}&amp;lt;/math&amp;gt; jest jedną z kolumn macierzy &amp;lt;math&amp;gt;\mathbf{D}^{-1}&amp;lt;/math&amp;gt;, to &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; jest jednym z poszukiwanych komponentów.&lt;br /&gt;
Zamieniając zmienne &amp;lt;math&amp;gt;\mathbf{z}=\mathbf{D}^{\mathsf{T}}\mathbf{w}&amp;lt;/math&amp;gt; możemy napisać &amp;lt;math&amp;gt;y = \mathbf{w}^{\mathsf{T}}\mathbf{x} = \mathbf{w}^{\mathsf{T}} \mathbf{D}\mathbf{s} = \mathbf{z}^{\mathsf{T}}\mathbf{s}&amp;lt;/math&amp;gt;. To uwidacznia fakt, że &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; jest liniową kombinacją składowych &amp;lt;math&amp;gt;s^{i}&amp;lt;/math&amp;gt; z wagami danymi przez &amp;lt;math&amp;gt;z_{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
Z centralnego twierdzenia granicznego wynika, że suma niezależnych zmiennych losowych ma  bardziej gaussowski charakter niż każda z tych zmiennych osobno. &lt;br /&gt;
Liniowa kombinacja staje się najmniej gaussowska gdy &amp;lt;math&amp;gt;\mathbf{z}&amp;lt;/math&amp;gt; ma tylko jeden element niezerowy. W tym przypadku &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; jest proporcjonalny do &amp;lt;math&amp;gt;s^{i}&amp;lt;/math&amp;gt;. &lt;br /&gt;
Zatem problem estymacji modelu ICAmoże być sformułowany jako problem znalezienia takiego &amp;lt;math&amp;gt;\mathbf{w}&amp;lt;/math&amp;gt; , który maksymalizuje niegaussowskość &amp;lt;math&amp;gt;y=\mathbf{w}^{\mathsf{T}}\mathbf{x}&amp;lt;/math&amp;gt;. &lt;br /&gt;
Maksymalizacja niegaussowskości &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; daje jeden niezależny komponent odpowiadający jednemu z &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; maksimów (bo mamy &amp;lt;math&amp;gt;s^{i}&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;-s^{i}&amp;lt;/math&amp;gt;) w krajobrazie optymalizacyjnym. Aby znaleźć wszystkie niezależne komponenty musimy znaleźć wszystkie maksima. Ponieważ komponenty są nieskorelowane, to poszukiwania kolejnych komponentów można kontynuować w podprzestrzeni ortogonalnej do już znalezionych komponentów.&lt;br /&gt;
&lt;br /&gt;
===Obliczenia===&lt;br /&gt;
Intuicyjna heurystyka poszukiwania najbardziej niegaussowskich składowych może być użyta do wyprowadzenia różnych funkcji kosztu, których optymalizacja daje model ICA, np. kurtoza. Procedura wykorzystywana w eeglabie (“runica”, Makeig 1996) dąży do minimalizacji informacji wzajemnej. Oba podejścia są w przybliżeniu równoważne (Hyvarinen, 2000), chociaż owo przybliżenie dla  sygnałów elektrofizjologicznych nie zostało to jeszcze w pełni wyeksplorowane.&lt;br /&gt;
Dla sygnałów o niskiej wymiarowości i spełniających dokładnie założenia ICA wszystkie powszechnie wykorzystywane algorytmy dają niemal identyczne wyniki.&lt;br /&gt;
&lt;br /&gt;
;Bardzo ważna uwaga: ogólną zasadą jest, że jeśli estymujemy &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; stabilnych komponentów  (z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-kanałowych danych) to musimy dysponować &amp;lt;math&amp;gt;k N^2&amp;lt;/math&amp;gt; punktami danych w każdym kanale, gdzie &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt;jest liczbą elementów w macierzy &amp;lt;math&amp;gt;\mathbf{D}&amp;lt;/math&amp;gt;, którą ICA próbuje wyestymować, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; jest liczbą całkowitą. Nie ma dobrych oszacowań teoretycznych na wielkość &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, z praktycznych obserwacji wynika, że rośnie on z ilością kanałów.&lt;br /&gt;
&lt;br /&gt;
=== Możliwe zastosowania ===&lt;br /&gt;
Najczęściej ICA jest stosowana jako narzędzie do:&lt;br /&gt;
* usuwania artefaktów z sygnałów EEG (ruchy oczu i mięśnie) &lt;br /&gt;
* wydobywania składowych do dalszej analizy (Onton, 2006)&lt;br /&gt;
* jako analiza wstępna do lokalizacji źródeł (Grau, 2007).&lt;br /&gt;
* ICA jest także stosowana w analize sygnałów EKG i EMG.&lt;br /&gt;
&lt;br /&gt;
===Bibliografia===&lt;br /&gt;
* Grau, C., Fuentemilla, L., Marco-Pallars, J. (2007). Functional neural dynamics underlying auditory event-related n1 and n1 suppression response. Neuroimage, 36(6):522–31.&lt;br /&gt;
* Hyvarinen, A. and Oja, E. (2000). Independent component analysis: Algorithms and applications. Neural Networks, 13(4-5):411–430.&lt;br /&gt;
* Makeig,S.,Bell,A.,Jung,T.-P., Sejnowski,T.(1996).Independentcomponent analysis of electroencephalographic data. W: Touretzky, D., Mozer, M., and Hasselmo, M., editors, Advances in Neural Information Processing Systems, volume 8, pages 145–151. MIT Press, Cambridge, MA.&lt;br /&gt;
* Onton,J., Makeig,S.(2006).Information-based modeling of event-related brain dynamics. Prog Brain Res., 159:99–120.&lt;br /&gt;
* Tutorial: http://sccn.ucsd.edu/wiki/Chapter_09:_Decomposing_Data_Using_ICA&lt;br /&gt;
* http://sccn.ucsd.edu/~arno/indexica.html&lt;br /&gt;
* http://cis.legacy.ics.tkk.fi/aapo/papers/IJCNN99_tutorialweb/&lt;br /&gt;
&lt;br /&gt;
=== Wydobywanie interesujących komponentów ===&lt;br /&gt;
&lt;br /&gt;
Dane do tej części ćwiczeń proszę pobrać i rozpakować w swoim katalogu:&lt;br /&gt;
http://www.fuw.edu.pl/~jarekz/LabEEG/Dane_do_ICA_alfa.tar.gz&lt;br /&gt;
&lt;br /&gt;
Pochodzą one z eksperymentu, w którym osoba badana siedziała z zamkniętymi oczami słuchając nagrania czytanego spokojnym głosem. Metadane opisujące sygnał znajdują się w pliku Miro.xml, zaś lokalizacje elektrod w pliku Miro-10-20-Cap.locs.&lt;br /&gt;
&lt;br /&gt;
Proszę:&lt;br /&gt;
* wczytać dane do eeglaba&lt;br /&gt;
* wyedytować lokalizację elektrod&lt;br /&gt;
* usunąć kanały nie zawierające EEG&lt;br /&gt;
* zmienić referencje na średnią z kanałów A1 i A2&lt;br /&gt;
* przefiltrować filtrem FIR górnoprzepustowym z częstością odcięcia 0,5 Hz&lt;br /&gt;
* obejrzeć wstępnie przygotowane dane&lt;br /&gt;
* policzyć ICA na całym sygnale &lt;br /&gt;
* obejrzeć właściwości otrzymanych komponentów&lt;br /&gt;
** Czy są wśród nich takie, które zawierają znaczny udział rytmu alfa?&lt;br /&gt;
** Jaka jest ich topografia?&lt;br /&gt;
* usunąć wszystkie komponenty nie zawierające alfy&lt;br /&gt;
* odtworzyć z tych komponentów sygnał na elektrodach&lt;br /&gt;
* wykoać dekompozycję ICA kilkukrotnie (co najmniej 3) i porównać wyniki&lt;br /&gt;
** Czy uzyskiwane komponenty są powtarzalne? &lt;br /&gt;
** Swoje wyniki porównać też z sąsiednimi grupami.&lt;br /&gt;
&lt;br /&gt;
=== Identyfikacja artefaktów ===&lt;br /&gt;
Proszę pobrać dane:&lt;br /&gt;
&lt;br /&gt;
*http://www.fuw.edu.pl/~jarekz/LabEEG/Arousal-10-20-Cap.locs&lt;br /&gt;
*http://www.fuw.edu.pl/~jarekz/LabEEG/Arousal1.set&lt;br /&gt;
*http://www.fuw.edu.pl/~jarekz/LabEEG/Arousal1.fdt&lt;br /&gt;
&lt;br /&gt;
Pochodzą one z eksprymentu w którym osoba badana czytała słowa o różych właściwościach wzbudznia emocji. &lt;br /&gt;
&lt;br /&gt;
* wczytaj je do eeglab'a&lt;br /&gt;
* wczytaj lokalizację kanałów z pliku Arousal-10-20-Cap.locs&lt;br /&gt;
* obejrzyj przebiegi czasowe&lt;br /&gt;
* odrzuć kanał z diodą (21) i z GSR (20)&lt;br /&gt;
* zrób dekompozycję ICA&lt;br /&gt;
* obejrzyj topografię komponentów. &lt;br /&gt;
* zidentyfikuj komponenty odpowiadające mruganiu i aktywności mięśniowej&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
==Filtry przestrzenne dla większej ilości warunków==&lt;br /&gt;
===FFDIAG===&lt;br /&gt;
===Analiza ERD/S z użyciem FFDIAG===&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczenia_ICA&amp;diff=4573</id>
		<title>AS cwiczenia ICA</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczenia_ICA&amp;diff=4573"/>
		<updated>2016-01-06T20:48:05Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Analiza składowych niezależnych */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Analiza składowych niezależnych==&lt;br /&gt;
&lt;br /&gt;
Ogólna zasada działania algorytmu analizy składowych niezależnych (''Independent Component Analysis'', ICA) została wprowadzona na [[Analiza_sygnałów_wielowymiarowych|wykładzie]]. &lt;br /&gt;
&lt;br /&gt;
Przypomnienie:&lt;br /&gt;
Rozważmy problem “cocktail party”, w którym próbujemy rozdzielić mieszaninę sygnałów zarejestrowanych przez kilka odbiorników znajdujących się w różnych miejscach na poszczególne źródła. Określając macierz sygnałów źródłowych, której kolumny oznaczają wartości sygnałów dla wszystkich źródeł w kolejnych chwilach czasu, jako &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, oraz macierz mieszanin, zawierającą kolejne próbki czasowe sygnałów zarejestrowanych przez odbiorniki, jako &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, możemy zapisać powyższą sytuację:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;x_i(t) = \sum_{j=1}^M{a_{ij} s_j(t)}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie w dowolnym punkcie czasowym &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, wartość &amp;lt;math&amp;gt;x_i(t)&amp;lt;/math&amp;gt; jest linową kombinacją wartości sygnałów źródłowych, z pewnymi stałymi współczynnikami mieszania &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;. Po zgrupowaniu współczynników mieszających w macierzy &amp;lt;math&amp;gt;\mathbf{A} = [a_{ij}] \in\mathbb{R}_{M \times M}&amp;lt;/math&amp;gt; model ten można zapisać za pomocą równania:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathbf{x} = \mathbf{A} \mathbf{s}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Przy pomocy tego modelu musimy wyestymować zarówno &amp;lt;math&amp;gt;\mathbf{A}&amp;lt;/math&amp;gt;, jak i &amp;lt;math&amp;gt;\mathbf{s}&amp;lt;/math&amp;gt;, dlatego zakładamy, że komponenty &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; są statystycznie ''niezależne'' i mają rozkład ''niegaussowski''. Zakładamy również, że macierz &amp;lt;math&amp;gt;\mathbf{A}&amp;lt;/math&amp;gt; jest kwadratowa. Dzięki temu, po wyestymowaniu macierzy &amp;lt;math&amp;gt;\mathbf{A}&amp;lt;/math&amp;gt;, obliczamy jej odwrotność &amp;lt;math&amp;gt;\mathbf{A}^{-1} = \mathbf{W}&amp;lt;/math&amp;gt; i otrzymujemy niezależne komponenty:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathbf{s} = \mathbf{W} \mathbf{x}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie 1===&lt;br /&gt;
&lt;br /&gt;
*Wygeneruj 3-kanałowy sygnał źródłowy &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; będący superpozycją sinusa o częstości 5 Hz, prostokąta i piły z odpowiednimi współczynnikami, określanymi jako współczynniki mieszania:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;&lt;br /&gt;
 A = np.array([[1, 1, 1], [2.0, 0.5, 1.0], [1.5, 1.5, 0.5]]).T&lt;br /&gt;
 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Przeprowadź dekompozycję sygnału przy pomocy implementacji ICA w pakiecie [http://scikit-learn.org/stable/ scikit-learn]. W tym celu należy zaimportować funkcję &amp;lt;tt&amp;gt;FastICA&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from sklearn.decomposition import FastICA&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dekompozycja ICA wygląda następująco:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
ica = FastICA(n_components=3) # liczba komponentów równa jest liczbie kanałów&lt;br /&gt;
S_ = ica.fit_transform(X) # macierz zrekonstruowanych sygnałów źródłowych S; X jest macierzą mieszanin&lt;br /&gt;
A_ = ica.mixing_ # wyestymowana macierz mieszająca&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Następnie porównaj otrzymany wynik z wynikiem dekompozycji przeprowadzonej przy pomocy programu Svarog. W tym celu wyeksportuj sygnał do pliku binarnego, a następnie wybierz Tools -&amp;gt; Independent Component Analysis -&amp;gt; Compute ICA.&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie 2===&lt;br /&gt;
&lt;br /&gt;
Wczytaj przy pomocy pythona sygnały [[Plik:sounds.rar|audio]] x1, x2 i x3 zarejestrowane przez trzy odbiorniki. Użyj do tego modułu &amp;lt;tt&amp;gt;scipy.io.wavfile&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from scipy.io import wavfile&lt;br /&gt;
&lt;br /&gt;
rate, x1 = wavfile.read('x1.wav')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Następnie przeprowadź dekompozycję ICA. Zapisz otrzymane komponenty do plików audio:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from scipy.io import wavfile&lt;br /&gt;
&lt;br /&gt;
wavfile.write('ica_s1.wav', rate, ica_s1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i porównaj z orginalnymi sygnałami źródłowymi.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
*Wczytaj do Svaroga 10-minutowy fragment [[Plik:EEG-resting.bin| zapisu spoczynkowego EEG]] zarejestrowanego, kiedy osoba badana miała oczy zamknięte. Przeprowadź analizę ICA. Co można powiedzieć o rozkładzie przestrzennym wybranych komponentów i ich zawartości spektralnej? --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczeniaTF&amp;diff=4453</id>
		<title>AS cwiczeniaTF</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczeniaTF&amp;diff=4453"/>
		<updated>2015-12-13T11:48:08Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Ćwiczenie 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Metody czas-częstość==&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie 1===&lt;br /&gt;
&lt;br /&gt;
*Wygeneruj sygnał o długości 1 sek. będący sumą sinusa, delty Diraca i trzech funkcji Gabora o parami jednakowych położeniach w czasie i częstościach. Przyjmij częstość próbkowania 512 Hz.  &lt;br /&gt;
*Do wygenerowanego sygnału dodaj szum o energii dwukrotnie większej niż sam sygnał.&lt;br /&gt;
*W programie Svarog utwórz mapę gęstości energii sygnału w przestrzeni czas-częstość przy pomocy spektrogramu, transformacji falkowej oraz algorytmu ''matching pursuit''.&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie 2===&lt;br /&gt;
&lt;br /&gt;
Przy pomocy programu Svarog wczytaj sygnał [[Plik:finger_movement.rar| EEG]] pochodzący z eksperymentu, w którym osoba badana miała za zadanie co dziesięć sekund wykonywać ruch palcem (zaczynając od piątej sekundy). Momenty określające ruch zostały zapisane w pliku .tag. W pliku .xml znajdują się metadane rejestracji, takie jak częstość próbkowania, nazwy kanałów itp. &lt;br /&gt;
&lt;br /&gt;
*Wyznacz średni potencjał wywołany: Tools -&amp;gt; Average evoked potentials (w zakresie [-5 5], gdzie 0 oznacza moment wykonania ruchu) i wyeksportuj wynik do pliku (Save segments to file).&lt;br /&gt;
*Przeprowadź dekompozycję uśrednionego potencjału przy pomocy algorytmu ''matching pursuit'' i zapisz mapę czas-częstość. &lt;br /&gt;
*Następnie dla każdego fragmentu przeprowadź dekompozycję ''matching pursuit'' i uśrednij otrzymane mapy gęstości energii sygnału. Porównaj otrzymane wyniki.&lt;br /&gt;
*Porównaj wyniki z mapą czas-częstość zaprezentowaną w orginalnym artykule [1].&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczeniaTF&amp;diff=4439</id>
		<title>AS cwiczeniaTF</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczeniaTF&amp;diff=4439"/>
		<updated>2015-12-08T23:38:44Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Metody czas-częstość */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Metody czas-częstość==&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie 1===&lt;br /&gt;
&lt;br /&gt;
*Wygeneruj sygnał o długości 1 sek. będący sumą sinusa, delty Diraca i trzech funkcji Gabora o parami jednakowych położeniach w czasie i częstościach. Przyjmij częstość próbkowania 512 Hz.  &lt;br /&gt;
*Do wygenerowanego sygnału dodaj szum o energii dwukrotnie większej niż sam sygnał.&lt;br /&gt;
*W programie Svarog utwórz mapę gęstości energii sygnału w przestrzeni czas-częstość przy pomocy spektrogramu, transformacji falkowej oraz algorytmu ''matching pursuit''.&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie 2===&lt;br /&gt;
&lt;br /&gt;
Przy pomocy programu Svarog wczytaj sygnał [[Plik:finger_movement.rar| EEG]] pochodzący z eksperymentu, w którym osoba badana miała za zadanie co dziesięć sekund wykonywać ruch palcem (zaczynając od piątej sekundy). Momenty określające ruch zostały zapisane w pliku .tag. W pliku .xml znajdują się metadane rejestracji, takie jak częstość próbkowania, nazwy kanałów itp. &lt;br /&gt;
&lt;br /&gt;
*Wyznacz średni potencjał wywołany: Tools -&amp;gt; Average evoked potentials (w zakresie [-5 5], gdzie 0 oznacza moment wykonania ruchu) i wyeksportuj wynik do pliku (Save segments to file).&lt;br /&gt;
*Przeprowadź dekompozycję uśrednionego potencjału przy pomocy algorytmu 'matching pursuit'' i zapisz mapę czas-częstość. &lt;br /&gt;
*Następnie dla każdego fragmentu przeprowadź dekompozycję ''matching pursuit'' i uśrednij otrzymane mapy gęstości energii sygnału. Porównaj otrzymane wyniki.&lt;br /&gt;
*Porównaj wyniki z mapą czas-częstość zaprezentowaną w orginalnym artykule [1].&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczenia_ICA&amp;diff=4438</id>
		<title>AS cwiczenia ICA</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczenia_ICA&amp;diff=4438"/>
		<updated>2015-12-08T22:57:37Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Ćwiczenie 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Analiza składowych niezależnych==&lt;br /&gt;
&lt;br /&gt;
Ogólna zasada działania algorytmu analizy składowych niezależnych (''Independent Component Analysis'', ICA) została wprowadzona na [[Analiza_sygnałów_wielowymiarowych|wykładzie]]. &lt;br /&gt;
&lt;br /&gt;
Przypomnienie:&lt;br /&gt;
Rozważmy problem “cocktail party”, w którym próbujemy rozdzielić mieszaninę sygnałów zarejestrowanych przez kilka odbiorników znajdujących się w różnych miejscach na poszczególne źródła. Określając macierz sygnałów źródłowych, której kolumny oznaczają wartości sygnałów dla wszystkich źródeł w kolejnych chwilach czasu, jako &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, oraz macierz mieszanin, zawierającą kolejne próbki czasowe sygnałów zarejestrowanych przez odbiorniki, jako &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, możemy zapisać powyższą sytuację:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;x_i^t = \sum_{j=1}^M{a_{ij} s_j^t}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie w dowolnym punkcie czasowym &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, wartość &amp;lt;math&amp;gt;x_i^t&amp;lt;/math&amp;gt; jest linową kombinacją wartości sygnałów źródłowych, z pewnymi stałymi współczynnikami mieszania &amp;lt;math&amp;gt;a_i^j&amp;lt;/math&amp;gt;. Po zgrupowaniu współczynników mieszających w macierzy &amp;lt;math&amp;gt;\mathbf{A} = [a_{ij}] \in\mathbb{R}_{M \times M}&amp;lt;/math&amp;gt; model ten można zapisać za pomocą równania:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathbf{x} = \mathbf{A} \mathbf{s}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Przy pomocy tego modelu musimy wyestymować zarówno &amp;lt;math&amp;gt;\mathbf{A}&amp;lt;/math&amp;gt;, jak i &amp;lt;math&amp;gt;\mathbf{s}&amp;lt;/math&amp;gt;, dlatego zakładamy, że komponenty &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; są statystycznie ''niezależne'' i mają rozkład ''niegaussowski''. Zakładamy również, że macierz &amp;lt;math&amp;gt;\mathbf{A}&amp;lt;/math&amp;gt; jest kwadratowa. Dzięki temu, po wyestymowaniu macierzy &amp;lt;math&amp;gt;\mathbf{A}&amp;lt;/math&amp;gt;, obliczamy jej odwrotność &amp;lt;math&amp;gt;\mathbf{A}^{-1} = \mathbf{W}&amp;lt;/math&amp;gt; i otrzymujemy niezależne komponenty:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathbf{s} = \mathbf{W} \mathbf{x}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie 1===&lt;br /&gt;
&lt;br /&gt;
*Wygeneruj 3-kanałowy sygnał źródłowy &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; będący superpozycją sinusa o częstości 5 Hz, prostokąta i piły z odpowiednimi współczynnikami, określanymi jako współczynniki mieszania:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;&lt;br /&gt;
 A = np.array([[1, 1, 1], [2.0, 0.5, 1.0], [1.5, 1.5, 0.5]]).T&lt;br /&gt;
 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Przeprowadź dekompozycję sygnału przy pomocy implementacji ICA w pakiecie [http://scikit-learn.org/stable/ scikit-learn]. W tym celu należy zaimportować funkcję &amp;lt;tt&amp;gt;FastICA&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from sklearn.decomposition import FastICA&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dekompozycja ICA wygląda następująco:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
ica = FastICA(n_components=3) # liczba komponentów równa jest liczbie kanałów&lt;br /&gt;
S_ = ica.fit_transform(X) # macierz zrekonstruowanych sygnałów źródłowych S; X jest macierzą mieszanin&lt;br /&gt;
A_ = ica.mixing_ # wyestymowana macierz mieszająca&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Następnie porównaj otrzymany wynik z wynikiem dekompozycji przeprowadzonej przy pomocy programu Svarog. W tym celu wyeksportuj sygnał do pliku binarnego, a następnie wybierz Tools -&amp;gt; Independent Component Analysis -&amp;gt; Compute ICA.&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie 2===&lt;br /&gt;
&lt;br /&gt;
Wczytaj przy pomocy pythona sygnały [[Plik:sounds.rar|audio]] x1, x2 i x3 zarejestrowane przez trzy odbiorniki. Użyj do tego modułu &amp;lt;tt&amp;gt;scipy.io.wavfile&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from scipy.io import wavfile&lt;br /&gt;
&lt;br /&gt;
rate, x1 = wavfile.read('x1.wav')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Następnie przeprowadź dekompozycję ICA. Zapisz otrzymane komponenty do plików audio:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from scipy.io import wavfile&lt;br /&gt;
&lt;br /&gt;
wavfile.write('ica_s1.wav', rate, ica_s1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i porównaj z orginalnymi sygnałami źródłowymi.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
*Wczytaj do Svaroga 10-minutowy fragment [[Plik:EEG-resting.bin| zapisu spoczynkowego EEG]] zarejestrowanego, kiedy osoba badana miała oczy zamknięte. Przeprowadź analizę ICA. Co można powiedzieć o rozkładzie przestrzennym wybranych komponentów i ich zawartości spektralnej? --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczenia_ICA&amp;diff=4437</id>
		<title>AS cwiczenia ICA</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczenia_ICA&amp;diff=4437"/>
		<updated>2015-12-08T22:56:31Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Analiza składowych niezależnych */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Analiza składowych niezależnych==&lt;br /&gt;
&lt;br /&gt;
Ogólna zasada działania algorytmu analizy składowych niezależnych (''Independent Component Analysis'', ICA) została wprowadzona na [[Analiza_sygnałów_wielowymiarowych|wykładzie]]. &lt;br /&gt;
&lt;br /&gt;
Przypomnienie:&lt;br /&gt;
Rozważmy problem “cocktail party”, w którym próbujemy rozdzielić mieszaninę sygnałów zarejestrowanych przez kilka odbiorników znajdujących się w różnych miejscach na poszczególne źródła. Określając macierz sygnałów źródłowych, której kolumny oznaczają wartości sygnałów dla wszystkich źródeł w kolejnych chwilach czasu, jako &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, oraz macierz mieszanin, zawierającą kolejne próbki czasowe sygnałów zarejestrowanych przez odbiorniki, jako &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, możemy zapisać powyższą sytuację:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;x_i^t = \sum_{j=1}^M{a_{ij} s_j^t}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie w dowolnym punkcie czasowym &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, wartość &amp;lt;math&amp;gt;x_i^t&amp;lt;/math&amp;gt; jest linową kombinacją wartości sygnałów źródłowych, z pewnymi stałymi współczynnikami mieszania &amp;lt;math&amp;gt;a_i^j&amp;lt;/math&amp;gt;. Po zgrupowaniu współczynników mieszających w macierzy &amp;lt;math&amp;gt;\mathbf{A} = [a_{ij}] \in\mathbb{R}_{M \times M}&amp;lt;/math&amp;gt; model ten można zapisać za pomocą równania:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathbf{x} = \mathbf{A} \mathbf{s}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Przy pomocy tego modelu musimy wyestymować zarówno &amp;lt;math&amp;gt;\mathbf{A}&amp;lt;/math&amp;gt;, jak i &amp;lt;math&amp;gt;\mathbf{s}&amp;lt;/math&amp;gt;, dlatego zakładamy, że komponenty &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; są statystycznie ''niezależne'' i mają rozkład ''niegaussowski''. Zakładamy również, że macierz &amp;lt;math&amp;gt;\mathbf{A}&amp;lt;/math&amp;gt; jest kwadratowa. Dzięki temu, po wyestymowaniu macierzy &amp;lt;math&amp;gt;\mathbf{A}&amp;lt;/math&amp;gt;, obliczamy jej odwrotność &amp;lt;math&amp;gt;\mathbf{A}^{-1} = \mathbf{W}&amp;lt;/math&amp;gt; i otrzymujemy niezależne komponenty:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\mathbf{s} = \mathbf{W} \mathbf{x}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie 1===&lt;br /&gt;
&lt;br /&gt;
*Wygeneruj 3-kanałowy sygnał źródłowy &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; będący superpozycją sinusa o częstości 5 Hz, prostokąta i piły z odpowiednimi współczynnikami, określanymi jako współczynniki mieszania:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;&lt;br /&gt;
 A = np.array([[1, 1, 1], [2.0, 0.5, 1.0], [1.5, 1.5, 0.5]]).T&lt;br /&gt;
 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Przeprowadź dekompozycję sygnału przy pomocy implementacji ICA w pakiecie [http://scikit-learn.org/stable/ scikit-learn]. W tym celu należy zaimportować funkcję &amp;lt;tt&amp;gt;FastICA&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from sklearn.decomposition import FastICA&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dekompozycja ICA wygląda następująco:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
ica = FastICA(n_components=3) # liczba komponentów równa jest liczbie kanałów&lt;br /&gt;
S_ = ica.fit_transform(X) # macierz zrekonstruowanych sygnałów źródłowych S; X jest macierzą mieszanin&lt;br /&gt;
A_ = ica.mixing_ # wyestymowana macierz mieszająca&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Następnie porównaj otrzymany wynik z wynikiem dekompozycji przeprowadzonej przy pomocy programu Svarog. W tym celu wyeksportuj sygnał do pliku binarnego, a następnie wybierz Tools -&amp;gt; Independent Component Analysis -&amp;gt; Compute ICA.&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie 2===&lt;br /&gt;
&lt;br /&gt;
Wczytaj przy pomocy pythona sygnały [[Plik:sounds.rar|audio]] x1, x2 i x3 zarejestrowane przez trzy odbiorniki. Użyj do tego modułu &amp;lt;tt&amp;gt;scipy.io.wavfile&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from scipy.io import wavfile&lt;br /&gt;
&lt;br /&gt;
rate, x1 = wavfile.read('x1.wav')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Następnie przeprowadź dekompozycję ICA. Zapisz otrzymane komponenty do plików audio:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from scipy.io import wavfile&lt;br /&gt;
&lt;br /&gt;
wavfile.write('ica_s1.wav')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i porównaj z orginalnymi sygnałami źródłowymi.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
*Wczytaj do Svaroga 10-minutowy fragment [[Plik:EEG-resting.bin| zapisu spoczynkowego EEG]] zarejestrowanego, kiedy osoba badana miała oczy zamknięte. Przeprowadź analizę ICA. Co można powiedzieć o rozkładzie przestrzennym wybranych komponentów i ich zawartości spektralnej? --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=Analiza_sygna%C5%82%C3%B3w_-_%C4%87wiczenia&amp;diff=4436</id>
		<title>Analiza sygnałów - ćwiczenia</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=Analiza_sygna%C5%82%C3%B3w_-_%C4%87wiczenia&amp;diff=4436"/>
		<updated>2015-12-08T20:45:31Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Przedmioty specjalizacyjne]]&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#[[Systemy liniowe niezmiennicze w czasie | Systemy liniowe niezmiennicze w czasie]]&lt;br /&gt;
[[Ćwiczenia 8|Filtrowanie obrazów]]&lt;br /&gt;
[[Ćwiczenia 9|Analiza czas-częstość]]&lt;br /&gt;
[[Ćwiczenia 10|Analiza czas-częstość &amp;amp;mdash; STFT i transformata falkowa]]&lt;br /&gt;
[[Ćwiczenia 11|Analiza czas-częstość &amp;amp;mdash; reprezentacje energetyczne]]&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[ZasadyZaliczenia|Zasady zaliczenia ćwiczeń]]&lt;br /&gt;
&lt;br /&gt;
#[[Ćwiczenia 1|Sygnały]] &amp;lt;!-- -- wstęp, generacja sygnaów testowych, aliasing, przypomnienie Pythona, wprowadzenie Svaroga; jak wczytać do Svaroga z Pythona i w drugą stronę --&amp;gt;&lt;br /&gt;
#[[Ćwiczenia 2|Transformata Fouriera]] i [[Ćwiczenia 2_2|Transformata Fouriera cd]] &amp;lt;!-- piszemy w Pythonie, porównujemy ze Svarogiem --&amp;gt;&lt;br /&gt;
#[[Ćwiczenia 3|Okienkowanie sygnału i transformata Fouriera]], [[Nieparametryczne widmo mocy |Estymacja widma mocy w oparciu o transformatę Fouriera]] &amp;lt;!-- widmo średniej vs. średnie widmo --&amp;gt;&lt;br /&gt;
#[[Ćwiczenia 6|Filtry I]] &amp;lt;!-- w Pythonie i w Svarogu --&amp;gt;&lt;br /&gt;
#[[Ćwiczenia 7|Filtry II]] &amp;lt;!-- oglądanie charakterystyk filtrów, ogładanie widma sygnałów przefiltrowanych, efektywność filtrów, przesuwanie fazy --&amp;gt;&lt;br /&gt;
#[[Ćwiczenia 4|Funkcja autokorelacji i procesy AR]]&lt;br /&gt;
#[[Ćwiczenia 5|Procesy AR]] &amp;lt;!-- AR w Pyhonie + DTF w Svarogu (MK) --&amp;gt;&lt;br /&gt;
#[[AS cwiczenia ICA| ICA]] &amp;lt;!-- montaże, ICA --&amp;gt;&lt;br /&gt;
#[[AS cwiczeniaTF|Metody czas-częstość]] &amp;lt;!-- STFT i falki --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--#[[AS cwiczeniaMP|Matching pursuit]] &amp;lt;!-- MP w Svarogu, zabawa parametrami dekompozycji, zabawa filtrowaniem map w Svarogu, postprocessing w Pythonie &lt;br /&gt;
&lt;br /&gt;
# Uśrednianie gęstości energii vs gęstość energii uśrednionego sygnału: symulacje, ERD/S&lt;br /&gt;
#[[Ćwiczenia UNIFIKACJA]] &amp;lt;!-- ostatnie ćwiczenia na ktrych porównujemy na tych samych sygnałach rzeczywistych i symulowanych działanie różnych metod -- MMP vs DTF vs ICA, STFT vs WT vs MP itp, potrzebne fajne przykłady --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
autorzy: Jarosław Żygierewicz, Maciej Kamiński, Magdalena Zieleniewska&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== INFORMACJE DODATKOWE ==&lt;br /&gt;
Materiały 2014/2015&lt;br /&gt;
# [[kolokwia2013_2014|Informacje o zaliczeniu ćwiczeń]] &lt;br /&gt;
# [[kolokwia2014_2015_kol1|Zagadnienia przygotowawcze do 1 kolokwium]] &lt;br /&gt;
# [[Projekt2014|Projekt zaliczeniowy]]&lt;br /&gt;
&lt;br /&gt;
Materiały 2013/2014&lt;br /&gt;
# [[Plik:Zadania_powtorzeniowe.pdf|Zadania powtorzeniowe do 2 kolokwium]]&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczeniaTF&amp;diff=4434</id>
		<title>AS cwiczeniaTF</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczeniaTF&amp;diff=4434"/>
		<updated>2015-12-01T13:26:48Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: Utworzono nową stronę &amp;quot;==Metody czas-częstość==  ===Ćwiczenie 1===  *Wygeneruj sygnał o długości 1 sek. będący sumą sinusa, delty Diraca i trzech funkcji Gabora o parami jednakowych...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Metody czas-częstość==&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie 1===&lt;br /&gt;
&lt;br /&gt;
*Wygeneruj sygnał o długości 1 sek. będący sumą sinusa, delty Diraca i trzech funkcji Gabora o parami jednakowych położeniach w czasie i częstościach. Przyjmij częstość próbkowania 512 Hz.  &lt;br /&gt;
*Do wygenerowanego sygnału dodaj szum o energii dwukrotnie większej niż sam sygnał.&lt;br /&gt;
*W programie Svarog utwórz mapę gęstości energii sygnału w przestrzeni czas-częstość przy pomocy spektrogramu, transformacji falkowej oraz algorytmu ''matching pursuit''.&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczenia_ICA&amp;diff=4433</id>
		<title>AS cwiczenia ICA</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczenia_ICA&amp;diff=4433"/>
		<updated>2015-12-01T10:56:22Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Analiza składowych niezależnych */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Analiza składowych niezależnych==&lt;br /&gt;
&lt;br /&gt;
Ogólna zasada działania algorytmu analizy składowych niezależnych (''Independent Component Analysis'', ICA) została wprowadzona na [[Analiza_sygnałów_wielowymiarowych|wykładzie]]. &lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie 1===&lt;br /&gt;
&lt;br /&gt;
*Wygeneruj 3-kanałowy sygnał źródłowy &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; będący superpozycją sinusa o częstości 5 Hz, prostokąta i piły z odpowiednimi współczynnikami, określanymi jako współczynniki mieszania:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;&lt;br /&gt;
 A = np.array([[1, 1, 1], [2.0, 0.5, 1.0], [1.5, 1.5, 0.5]]).T&lt;br /&gt;
 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Przeprowadź dekompozycję sygnału przy pomocy implementacji ICA w pakiecie [http://scikit-learn.org/stable/ scikit-learn]. W tym celu należy zaimportować funkcję &amp;lt;tt&amp;gt;FastICA&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from sklearn.decomposition import FastICA&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dekompozycja ICA wygląda następująco:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
ica = FastICA(n_components=3) # liczba komponentów równa jest liczbie kanałów&lt;br /&gt;
S_ = ica.fit_transform(X) # macierz zrekonstruowanych sygnałów źródłowych S; X jest macierzą mieszanin&lt;br /&gt;
A_ = ica.mixing_ # wyestymowana macierz mieszająca&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Następnie porównaj otrzymany wynik z wynikiem dekompozycji przeprowadzonej przy pomocy programu Svarog. W tym celu wyeksportuj sygnał do pliku binarnego, a następnie wybierz Tools -&amp;gt; Independent Component Analysis -&amp;gt; Compute ICA.&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie 2===&lt;br /&gt;
&lt;br /&gt;
*Wczytaj do Svaroga 10-minutowy fragment [[Plik:EEG-resting.bin| zapisu spoczynkowego EEG]] zarejestrowanego, kiedy osoba badana miała oczy zamknięte. Przeprowadź analizę ICA. Co można powiedzieć o rozkładzie przestrzennym wybranych komponentów i ich zawartości spektralnej?&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczenia_ICA&amp;diff=4432</id>
		<title>AS cwiczenia ICA</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczenia_ICA&amp;diff=4432"/>
		<updated>2015-11-30T23:11:50Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Analiza składowych niezależnych */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Analiza składowych niezależnych==&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie 1===&lt;br /&gt;
&lt;br /&gt;
*Wygeneruj 3-kanałowy sygnał źródłowy &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; będący superpozycją sinusa o częstości 5 Hz, prostokąta i piły z odpowiednimi współczynnikami, określanymi jako współczynniki mieszania:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;&lt;br /&gt;
 A = np.array([[1, 1, 1], [2.0, 0.5, 1.0], [1.5, 1.5, 0.5]]).T&lt;br /&gt;
 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Przeprowadź dekompozycję sygnału przy pomocy implementacji ICA w pakiecie [http://scikit-learn.org/stable/ scikit-learn]. W tym celu należy zaimportować funkcję &amp;lt;tt&amp;gt;FastICA&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from sklearn.decomposition import FastICA&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dekompozycja ICA wygląda następująco:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
ica = FastICA(n_components=3) # liczba komponentów równa jest liczbie kanałów&lt;br /&gt;
S_ = ica.fit_transform(X) # macierz zrekonstruowanych sygnałów źródłowych S; X jest macierzą mieszanin&lt;br /&gt;
A_ = ica.mixing_ # wyestymowana macierz mieszająca&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Następnie porównaj otrzymany wynik z wynikiem dekompozycji przeprowadzonej przy pomocy programu Svarog. W tym celu wyeksportuj sygnał do pliku binarnego, a następnie wybierz Tools -&amp;gt; Independent Component Analysis -&amp;gt; Compute ICA.&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie 2===&lt;br /&gt;
&lt;br /&gt;
*Wczytaj do Svaroga 10-minutowy fragment [[Plik:EEG-resting.bin| zapisu spoczynkowego EEG]] zarejestrowanego, kiedy osoba badana miała oczy zamknięte. Przeprowadź analizę ICA. Co można powiedzieć o rozkładzie przestrzennym wybranych komponentów i ich zawartości spektralnej?&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczenia_ICA&amp;diff=4431</id>
		<title>AS cwiczenia ICA</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczenia_ICA&amp;diff=4431"/>
		<updated>2015-11-30T22:56:49Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Analiza składowych niezależnych==&lt;br /&gt;
&lt;br /&gt;
===Ćwiczenie 1===&lt;br /&gt;
&lt;br /&gt;
*Wygeneruj 3-kanałowy sygnał źródłowy &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; będący superpozycją sinusa o częstości 5 Hz, prostokąta i piły z odpowiednimi współczynnikami, określanymi jako współczynniki mieszania:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;&lt;br /&gt;
 A = np.array([[1, 1, 1], [2.0, 0.5, 1.0], [1.5, 1.5, 0.5]]).T&lt;br /&gt;
 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Przeprowadź dekompozycję sygnału przy pomocy implementacji ICA w pakiecie [http://scikit-learn.org/stable/ scikit-learn]. W tym celu należy zaimportować funkcję &amp;lt;tt&amp;gt;FastICA&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from sklearn.decomposition import FastICA&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dekompozycja ICA wygląda następująco:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
ica = FastICA(n_components=3) # liczba komponentów równa jest liczbie kanałów&lt;br /&gt;
S_ = ica.fit_transform(X) # macierz zrekonstruowanych sygnałów źródłowych S; X jest macierzą mieszanin&lt;br /&gt;
A_ = ica.mixing_ # wyestymowana macierz mieszająca&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Następnie porównaj otrzymany wynik z wynikiem dekompozycji przeprowadzonej przy pomocy programu Svarog. W tym celu wyeksportuj sygnał do pliku binarnego, a następnie wybierz Tools -&amp;gt; Independent Component Analysis -&amp;gt; Compute ICA.&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczenia_ICA&amp;diff=4430</id>
		<title>AS cwiczenia ICA</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=AS_cwiczenia_ICA&amp;diff=4430"/>
		<updated>2015-11-30T22:52:43Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: Utworzono nową stronę &amp;quot;===Analiza składowych niezależnych===  ==Ćwiczenie 1==  *Wygeneruj 3-kanałowy sygnał źródłowy &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; będący superpozycją sinusa o częstości 5 Hz, prosto...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Analiza składowych niezależnych===&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenie 1==&lt;br /&gt;
&lt;br /&gt;
*Wygeneruj 3-kanałowy sygnał źródłowy &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; będący superpozycją sinusa o częstości 5 Hz, prostokąta i piły z odpowiednimi współczynnikami, określanymi jako współczynniki mieszania:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;&lt;br /&gt;
 A = np.array([[1, 1, 1], [2.0, 0.5, 1.0], [1.5, 1.5, 0.5]]).T&lt;br /&gt;
 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Przeprowadź dekompozycję sygnału przy pomocy implementacji ICA w pakiecie [http://scikit-learn.org/stable/ scikit-learn]. W tym celu należy zaimportować funkcję &amp;lt;tt&amp;gt;FastICA&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from sklearn.decomposition import FastICA&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dekompozycja ICA wygląda następująco:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
ica = FastICA(n_components=3) # liczba komponentów równa jest liczbie kanałów&lt;br /&gt;
S_ = ica.fit_transform(X) # macierz zrekonstruowanych sygnałów źródłowych S; X jest macierzą mieszanin&lt;br /&gt;
A_ = ica.mixing_ # wyestymowana macierz mieszająca&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Następnie porównaj otrzymany wynik z wynikiem dekompozycji przeprowadzonej przy pomocy programu Svarog. W tym celu wyeksportuj sygnał do pliku binarnego, a następnie wybierz Tools -&amp;gt; Independent Component Analysis -&amp;gt; Compute ICA.&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_1&amp;diff=4262</id>
		<title>Ćwiczenia 1</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_1&amp;diff=4262"/>
		<updated>2015-10-06T10:19:29Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Przykład: eksport sygnału do pliku binarnego */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dokumentacja modułu scipy.signal ==&lt;br /&gt;
Proszę zapoznać się z dokumentacją biblioteki scipy.signal:&lt;br /&gt;
&lt;br /&gt;
http://docs.scipy.org/doc/scipy-0.14.0/reference/signal.html&lt;br /&gt;
&lt;br /&gt;
== Svarog: uruchamianie i konfiguracja ==&lt;br /&gt;
Zajęcia będziemy ilustrować przykładami realizowanymi w programie Svarog, który można pobrać [http://www.fuw.edu.pl/~durka/svarog-1.0.10.zip stąd]. Po rozpakowaniu paczki do dowolnego katalogu należy uruchomić skrypt „run-svarog.sh”.&lt;br /&gt;
&lt;br /&gt;
W przypadku pracy na własnych komputerach, do prawidłowego uruchomienia pluginu do analizy sygnałów, z którego będziemy korzystać w dalszej części ćwiczeń, konieczne jest zainstalowanie środowiska Oracle Java SE w wersji 8, które można pobrać [http://www.oracle.com/technetwork/java/javase/downloads/index.html ze strony wydawcy]. Alternatywnie, użytkownicy systemu Ubuntu lub pokrewnych dystrybucji mogą zainstalować środowisko Java według instrukcji [http://www.webupd8.org/2012/09/install-oracle-java-8-in-ubuntu-via-ppa.html dostępnych na tej stronie].&lt;br /&gt;
&lt;br /&gt;
==Sygnały ciągłe i dyskretne ==&lt;br /&gt;
===Próbkowanie w czasie ===&lt;br /&gt;
Proszę powtórzyć sobie pojęcia:&lt;br /&gt;
* częstość próbkowania&lt;br /&gt;
* częstość Nyquista&lt;br /&gt;
* aliasing&lt;br /&gt;
&lt;br /&gt;
W poniższym ćwiczeniu chcemy zbadać efekt próbkowania sygnału w czasie. W komputerach nie mamy dostępu do sygnału ciągłego. Na nasze potrzeby wygenerujemy sygnały próbkowane z bardzo dużą częstością, które będą dla nas aproksymacją sygnałów ciągłych. Przy ich pomocy zaprezentujemy efekt utożsamiania (aliasingu).&lt;br /&gt;
&lt;br /&gt;
Proszę wytworzyć wektor reprezentujący czas &amp;amp;bdquo;prawie&amp;amp;rdquo; ciągły. Będzie to u nas 1000 wartości z przedziału [0,1) wziętych z odstępem 0,001.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
t = np.arange(0,1,0.001) # czas 'prawie ciągły'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Teraz proszę wygenerować dwie sinusoidy: jedną o częstości &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; a drugą o częstości &amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt;. Dla przypomnienia wyrażenie:&lt;br /&gt;
:&amp;lt;math&amp;gt; s(t) = \sin(2 \pi f t)&amp;lt;/math&amp;gt; możemy w pythonie zapisać:&lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
s = np.sin(2*np.pi*f*t)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Proszę [[TI/Matplotlib#Kilka_wykres.C3.B3w_we_wsp.C3.B3lnych_osiach|wykreślić]] obie sinusoidy.&lt;br /&gt;
&lt;br /&gt;
Teraz proszę spróbkować czas i nasze &amp;amp;bdquo;prawie&amp;amp;rdquo; ciągłe sinusoidy z okresem próbkowania 0,1. (Trzeba pobrać co 100 element, proszę posłużyć się [[Programowanie_z_Pythonem/Sekwencje#Wycinki|wycinkami]]) &amp;lt;!-- [[TI/Sekwencje|Struktury danych — sekwencje|wycinkami]]. --&amp;gt;&lt;br /&gt;
Na tle &amp;amp;bdquo;prawie&amp;amp;rdquo; ciągłych sinusoid proszę dorysować punkty ze spróbkowanych sygnałów. Aby punkty były dobrze  widoczne proponuję użyć markerów &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; oraz &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Proszę zaobserwować wzajemne położenie punktów. Czy można odróżnić sinusoidę o częstości &amp;amp;minus;1 od sinusoidy o częstości 9, jeśli obie są próbkowane z częstością 10? Jak można uogólnić tą obserwację?&lt;br /&gt;
  &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
t = np.arange(0,1,0.001) # czas 'prawie ciągły'&lt;br /&gt;
f1 = -1 # częstość sygnału 1&lt;br /&gt;
f2 = 9 # częstość sygnału 2&lt;br /&gt;
s1 = np.sin(2*np.pi*f1*t) # prawie ciągły sygnał o częstości f1&lt;br /&gt;
s2 = np.sin(2*np.pi*f2*t) # prawie ciągły sygnał o częstości f2&lt;br /&gt;
&lt;br /&gt;
T = 0.1 # okres próbkowania&lt;br /&gt;
Fs = 1/T # częstość próbkowania&lt;br /&gt;
FN = Fs/2 # częstość Nyquista&lt;br /&gt;
T_samp = t[0::100] # czas pobierania próbek&lt;br /&gt;
s1_samp = s1[0::100] # próbkowany sygnał o częstości f1&lt;br /&gt;
s2_samp = s2[0::100] # próbkowany sygnał o częstości f2&lt;br /&gt;
&lt;br /&gt;
py.plot(t, s1, 'g')&lt;br /&gt;
py.plot(t, s2, 'b')&lt;br /&gt;
py.plot(T_samp, s1_samp, 'gx', markersize=10)&lt;br /&gt;
py.plot(T_samp, s2_samp, 'r+', markersize=10)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===Błąd kwantyzacji ===&lt;br /&gt;
Kiedy mierzymy fizyczne wielkości w celu dalszej analizy najczęściej chcemy przypisać im pewne liczby. Liczby w systemach cyfrowych reprezentowane są ze skończoną dokładnością. Urządzenia dokonujące przypisania liczby do mierzonej wartości to przetworniki analogowo-cyfrowe (ang. ADC, Analog to Digital Converter).&lt;br /&gt;
Charakteryzują się one określoną ilością bitów ''N'', za pomocą których reprezentują liczby. Pełen zakres wartości pomiarowych ''R'' jest dzielony na &amp;lt;math&amp;gt;2^N&amp;lt;/math&amp;gt; poziomów. Błąd kwantyzacji szacujemy jako nie większy niż &amp;lt;math&amp;gt; \frac{R}{2^{N+1}} &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
====Zadanie:====&lt;br /&gt;
Proszę oszacować błąd kwantyzacji sygnału EEG mierzonego za pomocą 12-bitowego konwertera. Zakres pomiarowy tego urządzenia to &amp;amp;plusmn;200 &amp;amp;mu;V.&lt;br /&gt;
====Zadanie:====&lt;br /&gt;
Proszę zilustrować efekt kwantyzacji dla trzybitowego przetwornika o zakresie 2.&lt;br /&gt;
W tym celu proszę wykonać następujące kroki:&lt;br /&gt;
# wygenerować &amp;amp;bdquo;prawie&amp;amp;rdquo; ciągłą sinusoidę (częstość 1, czas trwania 1 próbkowanie co 0,001)&lt;br /&gt;
# spróbkować tą sinusoidę co 0,1 (proszę zastosować wycinki)&lt;br /&gt;
# proszę skwantować spróbkowane wartości &lt;br /&gt;
#Proszę wykreślić na jednym rysunku &lt;br /&gt;
#* oryginalny sygnał &lt;br /&gt;
#* sygnał spróbkowany w czasie&lt;br /&gt;
#* sygnał spróbkowany w czasie i o skwantowanej amplitudzie (skorzystać z funkcji &amp;lt;tt&amp;gt;py.step&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
{{ Wyjaśnienie|title= wskazówka: Kwantowanie | text = &lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
N_bits = 3&lt;br /&gt;
zakres = 2.0&lt;br /&gt;
dy = zakres/2**N_bits&lt;br /&gt;
s1_kwantowany = np.floor(s1_samp/dy)*dy +0.5*dy&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
t = np.arange(0,1,0.001) # czas 'prawie ciągły'&lt;br /&gt;
f1 = 1 # częstość sygnału 1&lt;br /&gt;
&lt;br /&gt;
s1 = np.sin(2*np.pi*f1*t) # prawie ciągły sygnał o częstości f1&lt;br /&gt;
T_samp = t[0::100]&lt;br /&gt;
s1_samp = s1[0::100]&lt;br /&gt;
&lt;br /&gt;
N_bits = 3&lt;br /&gt;
zakres = 2.0&lt;br /&gt;
dy = zakres/2**N_bits&lt;br /&gt;
s1_kwantowany = np.floor(s1_samp/dy)*dy +0.5*dy&lt;br /&gt;
ax = py.subplot(111)&lt;br /&gt;
py.plot(t,s1)&lt;br /&gt;
py.plot(T_samp,s1_samp,'ko',markersize = 5)&lt;br /&gt;
py.step(T_samp,s1_kwantowany,where = 'post')&lt;br /&gt;
&lt;br /&gt;
ax.set_xticks(T_samp)&lt;br /&gt;
poziomy = np.arange(-1+0.5*dy,1,dy)&lt;br /&gt;
ax.set_yticks(poziomy)&lt;br /&gt;
py.grid('on')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
for i in xrange(0,8):&lt;br /&gt;
	py.text(1.02,poziomy[i],bin(i))&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Sygnały testowe==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Generowanie sygnałów testowych ===&lt;br /&gt;
&lt;br /&gt;
Do badania różnych metod analizy sygnałów potrzebne nam będą sygnały o znanych własnościach. W szczególności dobrze jest umnieć nadać sygnałom występującym w postaci cyfrowej, oraz sztucznym sygnałom próbnym pewne własności fizyczne takie jak:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	czętość próbkowania&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	czas trwania&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	amplituda&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
=== Przykład sinus===&lt;br /&gt;
Sinus o zadanej częstości (w Hz), długości trwania, częstości próbkowania i fazie.&lt;br /&gt;
Poniższy kod implementuje i testuje funkcję &lt;br /&gt;
:&amp;lt;math&amp;gt; \sin(f,T,Fs,\phi) = \sin(2*\pi f t)&amp;lt;/math&amp;gt; dla &amp;lt;math&amp;gt;t \in \{0,T\}&amp;lt;/math&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang= python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1 Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
(s,t) = sin(f=10,Fs=1000)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
=== Przykład: eksport sygnału do pliku binarnego ===&lt;br /&gt;
* Poniższy kod ilustruje sposób zapisu dwóch funkcji sinus o częstościach 10 Hz i 21 Hz do pliku binarnego:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang= python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
T = 5&lt;br /&gt;
Fs = 128.0&lt;br /&gt;
&lt;br /&gt;
s1 = sin(f=10, T=T, Fs=Fs)&lt;br /&gt;
s2 = sin(f=21, T=T, Fs=Fs)	&lt;br /&gt;
	&lt;br /&gt;
signal = np.zeros((T*Fs, 2), dtype='&amp;lt;f')&lt;br /&gt;
signal[:, 0] = s1&lt;br /&gt;
signal[:, 1] = s2&lt;br /&gt;
&lt;br /&gt;
with open('test_signal.bin', 'wb') as f:&lt;br /&gt;
    signal.tofile(f)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Przykład: wczytanie sygnału do Svaroga ===&lt;br /&gt;
W celu wczytania zapisanego binarnie sygnału do programu Svarog, po wybraniu File -&amp;gt; Open signal, należy wprowadzić częstość próbkowania sygnału oraz liczbę kanałów. &lt;br /&gt;
&lt;br /&gt;
[[Plik:svarog_open_signal.png|center|800px|thumb|&amp;lt;figure id=&amp;quot;uid3&amp;quot; /&amp;gt;Wczytywanie sygnału w programie Svarog.]]&lt;br /&gt;
&lt;br /&gt;
=== Delta ===&lt;br /&gt;
Podobnie można zdefiniować funkcję delta o zadanym czasie trwania, częstości próbkowania i momencie wystąpienia impulsu:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt; \delta(t_0) = \left\{^{1 \quad t=t_0} _{0 \quad t \ne t_0} \right.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang= python&amp;gt;&lt;br /&gt;
def delta(t0=0.5, T=1  ,Fs = 128):&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	d = np.zeros(len(t))&lt;br /&gt;
	d[np.ceil(t0*Fs)]=1&lt;br /&gt;
	return (d,t)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Zadanie:===&lt;br /&gt;
Analogicznie do powyższych przykładów proszę zaimplementować i przetestować funkcje generujące:&lt;br /&gt;
* funkcję Gabora (funkcja Gaussa modulowana cosinusem) o zadanej częstości i standardowym odchyleniu w czasie, momencie wystąpienia, długości, częstości próbkowania i fazie. &lt;br /&gt;
:&amp;lt;math&amp;gt; g = \exp\left(-\frac{1}{2}\left(\frac{t-t_0}{\sigma}\right)^2 \right) \cdot  \cos(2 \pi f t + \phi); &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* szum gaussowski o zadanej średniej, odchyleniu standardowym, długości i częstości próbkowania.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- * pochodną funkcji Gaussa&lt;br /&gt;
&lt;br /&gt;
* połówkę funkcji Gaussa&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2&amp;diff=4261</id>
		<title>Ćwiczenia 2</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2&amp;diff=4261"/>
		<updated>2015-10-06T09:41:01Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Zadanie */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Transformata Fouriera==&lt;br /&gt;
=== Szereg Fouriera ===&lt;br /&gt;
Ciągłą funkcję  okresową (sygnał okresowy) można przedstawić w postaci  [[Szereg_Fouriera|szeregu Fouriera]] &amp;amp;mdash; czyli sumy zespolonych funkcji exponencjalnych. Współczynniki w szeregu Fouriera to liczby, w ogólności zespolone, które mówią z jaką amplitudą i z jaką fazą wchodzi odpowiadająca mu  funkcja, współczynniki te numerowane są od &amp;lt;math&amp;gt;-\infty&amp;lt;/math&amp;gt; do &amp;lt;math&amp;gt;\infty&amp;lt;/math&amp;gt;. Dla sygnałów rzeczywistych współczynniki występują parami co powoduje, że zgodnie ze wzorami Eulera:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
e^{ix}=\cos x + i\sin x \quad \Rightarrow \begin{cases}\cos x = \frac12(e^{ix}+e^{-ix})\\ \sin x = \frac{1}{2i}(e^{ix}-e^{-ix}) \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
szereg można zwinąć do szeregu funkcji sinusoidalnych.&lt;br /&gt;
&lt;br /&gt;
=== Zadanie ===&lt;br /&gt;
Proszę narysować wykres funkcji &amp;lt;math&amp;gt;f(t) = c \left(e^{i2 \pi \frac{  n  }{T}t } + e^{-i 2 \pi \frac{ n }{T} t  }\right) &amp;lt;/math&amp;gt; dla &amp;lt;math&amp;gt;t \in (-\pi,\, \pi); \quad T = 2 \pi&amp;lt;/math&amp;gt;. &lt;br /&gt;
* Obejrzeć wykresy dla &amp;lt;math&amp;gt;n \in \{0, 1, 2, 5\}&amp;lt;/math&amp;gt;. &lt;br /&gt;
* Jaki sens ma liczba &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;? &lt;br /&gt;
* Jaki sens ma liczba &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;?&lt;br /&gt;
&lt;br /&gt;
===  Obliczanie transformaty ===&lt;br /&gt;
====Przykład ====&lt;br /&gt;
'''Oblicz analitycznie''',  [[Szereg_Fouriera|korzystając ze wzorów]] współczynniki Fouriera dla funkcji ''f''. Za pomocą wykresu coraz to większej ilości składników otrzymanego szeregu sprawdź zbieżność szeregu. &lt;br /&gt;
Funkcja  o okresie 2, w podstawowym okresie dana jest ona wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt; f(t)=|t| &amp;lt;/math&amp;gt; dla &amp;lt;math&amp;gt;|t|&amp;lt;1  &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
Musimy obliczyć następującą całkę:&lt;br /&gt;
:&amp;lt;math&amp;gt; c_n = \frac{1}{2} \int_{-1}^1 {|t| e^{\frac{2 \pi j n t }{2}} dt} = &lt;br /&gt;
\frac{1}{2} \left[ \int_{-1}^0{ -t e^{\pi j n t }dt} + \int_{0}^1 {t e^{\pi j n t }dt} \right]&amp;lt;/math&amp;gt;&lt;br /&gt;
Przypomnijmy sobie, że [http://www.wolframalpha.com/index.html np. korzystając ze strony WolframAlpha]:&lt;br /&gt;
:&amp;lt;math&amp;gt;\int x e^{ax}dx = \frac{1}{a^2} e^{ax} (ax-1) &amp;lt;/math&amp;gt;&lt;br /&gt;
Zatem nasze &amp;lt;math&amp;gt;c_n&amp;lt;/math&amp;gt;:&lt;br /&gt;
: &amp;lt;math&amp;gt;c_n = \frac{1}{\pi^2 n^2} &lt;br /&gt;
\left[ &lt;br /&gt;
- \left[ e^{\pi j n t} \frac{\pi j n t -1}{(\pi j n)^2} \right]_{-1}^0 &lt;br /&gt;
+&lt;br /&gt;
   \left[ e^{\pi j n t} \frac{\pi j n t -1 }{(\pi j n)^2}   \right]_{0}^1&lt;br /&gt;
\right] = &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; = \frac{1}{2 \pi^2 n^2} &lt;br /&gt;
\left[ -2+ \pi j n \left( e^{-\pi j n} - e^{\pi j n} \right) + \left( e^{-\pi j n} + e^{\pi j n} \right)&lt;br /&gt;
\right]&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Korzystając ze wzorów Eulera możemy zwinąć to wyrażenie do funkcji trygonometrycznych:&lt;br /&gt;
:&amp;lt;math&amp;gt;c_n =  \frac{1}{ \pi^2 n^2} (\cos(\pi n ) - \sin(\pi n)  -1)&amp;lt;/math&amp;gt;&lt;br /&gt;
'''Rekonstrukcja sygnałów: '''&lt;br /&gt;
Na podstawie wyników poprzedniego zadania proszę napisać program, który demonstruje jaki jest wynik składania coraz większej ilości czynników.&lt;br /&gt;
Poniższy kod implementuje sumowanie zadanej ilości składników szeregu i ilustruje wynik.&lt;br /&gt;
Proszę uruchomić go dla &amp;lt;tt&amp;gt;N={2, 4, 6, 20}&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W implementacji musimy zwrócić uwagę na fakt, że &amp;lt;math&amp;gt;\lim_{n \rightarrow 0} \frac{1}{ \pi^2 n^2} \left(\cos(\pi n )-\sin(\pi n)  -1\right) = \frac{1}{2}  &amp;lt;/math&amp;gt;&lt;br /&gt;
zaś dla pozostałych ''n'' całkowitych możemy uwzględnić, że &amp;lt;math&amp;gt; \sin(\pi n) = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
def skladnik_modul_t(n ):&lt;br /&gt;
	'''n - który element szeregu'''&lt;br /&gt;
	if n==0:&lt;br /&gt;
		c_n = 0.5&lt;br /&gt;
	else:&lt;br /&gt;
		c_n = 1/(np.pi**2 * n**2) * (-1  + np.cos(np.pi*n) )&lt;br /&gt;
	return c_n&lt;br /&gt;
	&lt;br /&gt;
t = np.arange(-4,4,0.1)&lt;br /&gt;
f = np.zeros(len(t))&lt;br /&gt;
&lt;br /&gt;
N = 10&lt;br /&gt;
c = []&lt;br /&gt;
for n in range(-N,N+1):&lt;br /&gt;
	cn = skladnik_modul_t(n)&lt;br /&gt;
	c.append(cn)&lt;br /&gt;
	f += cn * np.exp(-1j*2*np.pi*t*n/2.0)&lt;br /&gt;
py.plot(t,f)&lt;br /&gt;
for n in range(-N,N+1):&lt;br /&gt;
	print '%(c).4f'%{'c':c[n+N]}&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Zadanie ====&lt;br /&gt;
Analogicznie do powyższego przykładu proszę znaleźć i zbadać szereg Fouriera dla funkcji:&lt;br /&gt;
: &amp;lt;math&amp;gt; f(t) = |cos(t)|&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dyskretna Transformata Fouriera (DFT) ===&lt;br /&gt;
&lt;br /&gt;
W praktycznych zastosowaniach mamy do czynienia z sygnałami próbkowanymi o skończonej długości. Transformata Fouriera działąjąca na takich sygnałach nazywana jest Dyskretną Transformatą Fouriera, a algorytm najczęściej wykorzystywany do jej obliczania to szybka trasnsformata Fouriera (fast Fourier transform FFT). &lt;br /&gt;
Formułę na współczynniki FFT można otrzymać z [[Szereg_Fouriera|szeregu Fouriera]]. Załóżmy, że sygnał który chcemy przetransformować składa się z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; próbek.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; s =\{ s[0],\dots,s[n],\dots s[N-1]\}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
i próbki pobierane były co &amp;lt;math&amp;gt;T_s&amp;lt;/math&amp;gt; sekund. Zakładamy, że analizowany sygnał &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;  to jeden okres nieskończonego sygnału o  okresie  &amp;lt;math&amp;gt;T=N\cdot T_s&amp;lt;/math&amp;gt;. Wprowadźmy oznaczenie: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s[n]=s(nT_s)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Przepiszmy wzór na współczynniki szeregu Fouriera. Ponieważ sygnał jest teraz dyskretny, całka zamieni się na sumę Riemanna: pole będzie sumą pól prostokątów o bokach równych wartości funkcji podcałkowej w zadanych punktach &amp;lt;math&amp;gt;x(nT_s)exp(2i{\pi}knT_s/T)&amp;lt;/math&amp;gt; i odległości między punktami &amp;lt;math&amp;gt;T_s&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
 S[k] = \frac{1}{NT_s}\sum_{n=0}^{N-1}s(nT_s)e^{2i\pi\frac{knT_s}{NT_s}}T_s = \frac{1}{N}\sum_{n=0}^{N-1}s[n]e^{2i{\pi}\frac{kn}{N}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
DFT zaimplementowana w &amp;lt;tt&amp;gt;numpy.fft&amp;lt;/tt&amp;gt; jest określona jako:&lt;br /&gt;
:&amp;lt;math&amp;gt;A[k] =  \sum_{m=0}^{n-1} a[m] \exp\left\{-2\pi i{mk \over n}\right\}       \qquad k = 0,\ldots,n-1.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
DFT jest w ogólności zdefiniowane dla zespolonych argumentów i zwraca zespolone współczynniki. &lt;br /&gt;
Odwrotna dyskretna transformata Fouriera jest zdefiniowana jako:&lt;br /&gt;
:&amp;lt;math&amp;gt; a[m] = \frac{1}{n}\sum_{k=0}^{n-1}A[k]\exp\left\{2\pi i{mk\over n}\right\}&lt;br /&gt;
       \qquad m = 0,\ldots,n-1.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwróćmy uwagę, że różni się ona do transformaty ''wprost'' jedynie znakiem w exponencie i normalizacją &amp;lt;math&amp;gt;1/n&amp;lt;/math&amp;gt;.&lt;br /&gt;
    &lt;br /&gt;
Wartości zwracane przez &amp;lt;tt&amp;gt;fft(a,n)&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; sygnał, &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; ilość punktów transformaty) mają następujący ''standardowy'' porządek:    &lt;br /&gt;
Jeśli &amp;lt;tt&amp;gt;A = fft(a, n)&amp;lt;/tt&amp;gt;, to &lt;br /&gt;
* &amp;lt;tt&amp;gt;A[0]&amp;lt;/tt&amp;gt; zawiera składową stałą (średnią sygnału)&lt;br /&gt;
* &amp;lt;tt&amp;gt;A[1:n/2]&amp;lt;/tt&amp;gt; zawiera współczynniki odpowiadające dodatnim częstościom&lt;br /&gt;
* &amp;lt;tt&amp;gt;A[n/2+1:]&amp;lt;/tt&amp;gt; zawiera współczynniki odpowiadające ujemnym częstościom w kolejności od bardziej do mniej ujemnych.&lt;br /&gt;
* Dla parzystego ''n''  &amp;lt;tt&amp;gt;A[n/2]&amp;lt;/tt&amp;gt; reprezentuje dodatnia i ujemną częstość Nyquista i dla sygnałów rzeczywistych jest liczbą rzeczywistą. &lt;br /&gt;
* Dla nieparzystego &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;, element &amp;lt;tt&amp;gt;A[(n-1)/2]&amp;lt;/tt&amp;gt; zawiera współczynnik dla największej częstości dodatniej a element &amp;lt;tt&amp;gt;A[(n+1)/2]&amp;lt;/tt&amp;gt; zawiera współczynnik dla największej częstości ujemnej.&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;numpy.fft.fftfreq(len(A),1.0/Fs)&amp;lt;/tt&amp;gt; zwraca macierz częstości odpowiadających poszczególnym elementom wyjściowym.&lt;br /&gt;
&lt;br /&gt;
Składnia:  &amp;lt;tt&amp;gt;numpy.fft.fftfreq(n, d=1.0)&amp;lt;/tt&amp;gt;&lt;br /&gt;
Parametry:&lt;br /&gt;
:&amp;lt;tt&amp;gt;n : int&amp;lt;/tt&amp;gt; &amp;amp;mdash; długość okna.&lt;br /&gt;
:&amp;lt;tt&amp;gt;d : skalar&amp;lt;/tt&amp;gt; &amp;amp;mdash; okres próbkowania (odwrotność częstości próbkowania).&lt;br /&gt;
:Zwracane częstości są obliczane w następujący sposób:&lt;br /&gt;
:&amp;lt;tt&amp;gt;f = [0,1,...,n/2-1,-n/2,...,-1]/(d*n)&amp;lt;/tt&amp;gt;         jeśli &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; jest przyste&lt;br /&gt;
:&amp;lt;tt&amp;gt;f = [0,1,...,(n-1)/2,-(n-1)/2,...,-1]/(d*n) &amp;lt;/tt&amp;gt;  jeśli  &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; jest nieparzyste. &lt;br /&gt;
    &lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;numpy.fft.fftshift(A)&amp;lt;/tt&amp;gt; przestawia wektor wyjściowy &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt; i wektor częstości, tak aby częstość zero wypadała w środku. Zastosowanie funkcji &amp;lt;tt&amp;gt;numpy.fft.ifftshift(A)&amp;lt;/tt&amp;gt; odwraca działanie &amp;lt;tt&amp;gt;numpy.fft.fftshift(.)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
    &lt;br /&gt;
Jeśli potraktujemy wejście &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jako sygnał w dziedzinie czasu i policzymy &amp;lt;tt&amp;gt;A = fft(a)&amp;lt;/tt&amp;gt;, wówczas &amp;lt;tt&amp;gt;np.abs(A)&amp;lt;/tt&amp;gt; jest widmem amplitudowym, zaś &amp;lt;tt&amp;gt;np.abs(A)**2&amp;lt;/tt&amp;gt; jest widmem mocy. Można obliczyć także widmo fazowe za pomocą funkcji  &amp;lt;tt&amp;gt;np.angle(A)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Zadanie ====&lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować cosinusoidę oraz sinusoidę o długości 1 s, częstości 2 Hz próbkowaną 10 Hz. Proszę obliczyć współczynniki i wypisać je. &lt;br /&gt;
** Jakiego typu liczby otrzymaliśmy?&lt;br /&gt;
** Czy istnieją jakieś związki między współczynnikami?&lt;br /&gt;
** Jaki jest związek między długością wejściowego sygnału i wyjściowych współczynników?&lt;br /&gt;
&lt;br /&gt;
*Proszę wygenerować sygnał będący sumą sinusoid o częstościach f = 30 Hz i f = 21 Hz, amplitudach A = 2 i A = 5, fazach pi/3 i pi/4 oraz składowej stałej 0.5, o długości T = 5 s próbkowany 128 Hz.&lt;br /&gt;
**Narysuj wygenerowany sygnał.&lt;br /&gt;
**Oblicz współczynniki i wypisz je. Jakiego rodzaju liczby otrzymaliśmy? Jaki jest związek między długością wejściowego sygnału i wyjściowych współczynników?&lt;br /&gt;
** Jaki jest związek pomiędzy argumentami zwróconych współczynników a fazą rzeczywistych sygnałów wejściowych?&lt;br /&gt;
&lt;br /&gt;
=== Transformaty rzeczywiste i Hermitowskie ===&lt;br /&gt;
Jeśli sygnał wejściowy jest rzeczywisty to jego transformata jest hermitowska, tzn. współczynnik przy częstości &amp;lt;math&amp;gt;f_k&amp;lt;/math&amp;gt; jest sprzężony ze współczynnikiem przy częstości &amp;lt;math&amp;gt;-f_k&amp;lt;/math&amp;gt;. Oznacza to, że dla sygnałów rzeczywistych współczynniki przy ujemnych częstościach nie wnoszą żadnej dodatkowej informacji.  Rodzina funkcji  &amp;lt;tt&amp;gt;rfft&amp;lt;/tt&amp;gt; wykorzystuje tą symetrię i zwracają tylko dodatnią część widma włącznie z częstością Nyquista. Tak więc, &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; punktów rzeczywistych na wejściu daje na wyjściu &amp;lt;math&amp;gt;\frac{n}{2}+1&amp;lt;/math&amp;gt; punktów zespolonych. Funkcje odwrotne w tej rodzinie zakładają tą samą symetrię i aby na wyjściu uzyskać &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;  punktów rzeczywistych na wejściu trzeba podać &amp;lt;math&amp;gt;\frac{n}{2}+1&amp;lt;/math&amp;gt; wartości zespolonych.&lt;br /&gt;
    &lt;br /&gt;
Dla kompletności powiedzmy jeszcze, że możliwy jest przypadek odwrotny, tzn. widmo jest czysto rzeczywiste i odpowiada mu hermitowski sygnał zespolony. Tę symetrię wykorzystują funkcje &amp;lt;tt&amp;gt;hfft&amp;lt;/tt&amp;gt;, które zakładają, że operujemy w dziedzinie czasu &amp;lt;math&amp;gt;\frac{n}{2}+1&amp;lt;/math&amp;gt; punktami zespolonymi i odpowiadającymi im w dziedzinie częstości &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; punktami rzeczywistymi.&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4260</id>
		<title>Ćwiczenia 2 2</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4260"/>
		<updated>2015-10-06T09:17:08Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Współczynniki obliczane przez FFT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Zadania ===&lt;br /&gt;
&lt;br /&gt;
==== Współczynniki obliczane przez FFT ====&lt;br /&gt;
Najprostsza sytuacja: Badamy współczynniki zwracane przez &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt; dla sinusoid o różnych częstościach. Wykorzystujemy funkcje do generacji sygnałów napisane na poprzednich zajęciach.&lt;br /&gt;
 &amp;lt;!--&lt;br /&gt;
* Proszę kolejno wygenerować sinusoidy o długości 1s próbkowaną 128Hz i częstościach 1,10,30, 64  i  0 Hz. Dla tych sinusoid proszę policzyć transformaty Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wyglądają otrzymane wykresy?&lt;br /&gt;
** Czy coś szczególnego dzieje się dla częstości 0 i 64Hz? Czy w tych skrajnych przypadkach faza sygnału ma wpływ na wynik transformaty? &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał delta położony w sekundzie 0,5 na odcinku czasu o długości 1s próbkowany 128Hz. Dla takiego sygnału proszę policzyć transformatę Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wygląda transformata funkcji delta? Jakie częstości w sobie zawiera?&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
# skrypt implemetujący polecenia w sekcji&lt;br /&gt;
# Współczynniki obliczane przez FFT&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
def delta(t0=0.5, T=1  ,Fs = 128):&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	d = np.zeros(len(t))&lt;br /&gt;
	d[np.ceil(t0*Fs)]=1&lt;br /&gt;
	return (d,t)&lt;br /&gt;
 &lt;br /&gt;
# do pytania 1&lt;br /&gt;
(s,t) = sin(f=2,T=1,Fs=10,phi=np.pi/2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
print S&lt;br /&gt;
# na wydruku należy zauważyć, że wsółczynniki są zespolone i parami sprzężone&lt;br /&gt;
&lt;br /&gt;
# do pytania 2&lt;br /&gt;
(s,t) = sin(f=1,T=1,Fs=128,phi=np.pi/3) # f=0,10,30,64&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&lt;br /&gt;
# do pytania 3&lt;br /&gt;
(s,t) = delta(t0=0.5, T=1  ,Fs = 128)&lt;br /&gt;
&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(2)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Rekonstrukcja sygnału ze współczynników =====&lt;br /&gt;
Reprezentacja sygnałów w dziedzinie częstości jest dualna do reprezentacji  w dziedzinie czasu. To znaczy, że jedną reprezentację można przekształcić w drugą. Do przejścia z dziedziny czasu do częstości używaliśmy transformaty Fouriera (zaimplemantowanej w &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt;). Przejścia z dziedziny częstości do czasu dokonujemy przy pomocy odwrotnej transformaty Fouriera (zaimplementowanej jako &amp;lt;tt&amp;gt;ifft&amp;lt;/tt&amp;gt;. Mając (zespolone) współczynniki w dziedzinie częstości dla pewnego sygnału,możemy odzyskać jego przebieg czasowy.&lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał &amp;lt;math&amp;gt;s(t) = \sin(2\pi t \cdot 1)+\sin\left(2 \pi  t \cdot 3+\frac{\pi}{5}\right) &amp;lt;/math&amp;gt; o długości 2,5 s próbkowany 10 Hz, obliczyć jego transformatę Fouriera, a następnie zrekonstruować przebieg czasowy. Sygnał oryginalny i zrekonstruowany wykreślić na jednym rysunku.  Korzystając z naszych funkcji generację sygnału można zapisać tak:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
(s1,t) = sin(f=1, T=2.5, Fs=10, phi=0)&lt;br /&gt;
(s2,t) = sin(f=3, T=2.5, Fs=10, phi=np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Dla porównania proszę zrekonstruować sygnał korzystając jawnie z postaci odwrotnej transformaty Fouriera danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;x(n)=\frac{1}{N} \sum_{k=0}^{N-1} S[k] \cdot \exp\left(2j \pi n\frac{ k}{N}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
:Zwróćmy uwagę, że ''n'' w powyższym wzorze to indeksy punktów czasu, zatem wiążą się one z czasem zwracanym przez nasze funkcje następująco:&lt;br /&gt;
:&amp;lt;tt&amp;gt;n = np.arange(0,len(t),1)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
zatem kod rekonstruujący może być np. taki:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
n = np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
&lt;br /&gt;
def f1(dt):&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co dt	'''&lt;br /&gt;
	t = np.arange(0,2,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*t)+np.sin(2*np.pi*3*t+np.pi/5)#np.abs(t)#&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
dt = 0.1	&lt;br /&gt;
Fs = 1.0/dt&lt;br /&gt;
&lt;br /&gt;
(s1,t) = sin(f=1,T=2.5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2,t) = sin(f=3,T=2.5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
S = FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
N = len(t)&lt;br /&gt;
&lt;br /&gt;
s_ifft = FFT.ifft(S)&lt;br /&gt;
&lt;br /&gt;
n = np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.plot(t,s_ifft,'bo',markersize = 3 )&lt;br /&gt;
py.plot(t,(s_rekonstrukcja),'gx',markersize = 8)&lt;br /&gt;
py.plot(t,s,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Rekonstrukcja na dłuższym odcinku czasu:=====&lt;br /&gt;
Korzystając z wyników poprzedniego polecenia proszę porównać wykres funkcji zadanych wzorami dla odcinak czasu o długości 5s i rekonstrukcję sygnału o długości 5s otrzymanego ze współczynników Fouriera obliczonych dla 2,5s  odcinak czasu.&lt;br /&gt;
* Na jakim odcinku czasu sygnały są zgodne?&lt;br /&gt;
* Co dzieje się na dalszym odcinku czasu?&lt;br /&gt;
 *&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
dalszy ciąg poprzedniego kodu:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.figure(2)&lt;br /&gt;
(s1_d,t_d) = sin(f=1,T=5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2_d,t_d) = sin(f=3,T=5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s_d = s1_d + s2_d&lt;br /&gt;
&lt;br /&gt;
# rekonstrukcja bazująca na współczynnikach otzrzynmanych dla 2sek fragmentu sygnału&lt;br /&gt;
n=np.arange(0,len(t_d),1)&lt;br /&gt;
s_rekonstrukcja_dluga = np.zeros(len(t_d)) &lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja_dluga += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
py.plot(t_d,(s_rekonstrukcja_dluga),'gx-',markersize = 8)&lt;br /&gt;
py.plot(t_d,s_d,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Przykład:=====&lt;br /&gt;
Oblicz współczynniki numerycznie korzystając z &amp;lt;tt&amp;gt;numpy.fft.fft&amp;lt;/tt&amp;gt;, porównaj z otrzymanymi analitycznie. Zrób wykresy funkcji i wartości bezwzględnej transformaty. Dla funkcji ''f'' z poprzedniego przykładu danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt; f(t)=|t| &amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-1, 1]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1,&lt;br /&gt;
&lt;br /&gt;
Obliczamy współczynniki i robimy wykres:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def f1():&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co 0.1	'''&lt;br /&gt;
	dt = 0.1	&lt;br /&gt;
	t = np.arange(-1,1,dt)&lt;br /&gt;
	s = np.abs(t)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
Fs = 10.0&lt;br /&gt;
(s,t) = f1() #generuję sygnał&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.stem(t,s)&lt;br /&gt;
&lt;br /&gt;
S=FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
F = FFT.fftfreq(len(S),Fs) # obliczam skalę częstości &lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.stem(F,np.abs(S)/len(s)) # wykreślam widmo amplitudowe&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Porównujemy wyniki z wynikami analitycznymi:&lt;br /&gt;
* &amp;lt;math&amp;gt; f(t) = |cos(t)|&amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-\pi, \pi]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Efekt nieciągłości funkcji ====&lt;br /&gt;
* Wygenerować sinusoidę o następujących własnościach: f=10 Hz, T=1, Fs=100 Hz, i fazie = 1;&lt;br /&gt;
* Przy pomocy subplotów proszę sporządzić rysunek zgodnie z ponższym opisem:&lt;br /&gt;
** subplot(2,2,1): przebieg sygnału w czasie &lt;br /&gt;
** subplot(2,2,2): moduł jego transformaty Fouriera (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(len(s), 1/Fs)&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; to nasz sygnał),&lt;br /&gt;
** subplot(2,2,3): Proszę wykreślić trzykrotnie periodycznie powielony oryginalny sygnał. Można go skonstruować wywołując funkcję: &amp;lt;tt&amp;gt;s_period = np.concatenate((s,s,s))&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** subplot(2,2,4): moduł transformaty Fouriera &amp;lt;tt&amp;gt;s_period&amp;lt;/tt&amp;gt; (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(3*len(s), 1/Fs)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Powtórz te same kroki dla sinusa o częstości 10.3 Hz.&lt;br /&gt;
Pytania:&lt;br /&gt;
# Czym różnią się przedłużenia sinusoidy 10 Hz od sinusoidy 10.3 Hz? Proszę zwrócić uwagę na miejsca sklejania sygnałów. &amp;lt;!--Porównaj z wynikami otrzymanymi w zagadnieniu '''Rekonstrukcja na dłuższym odcinku czasu'''.--&amp;gt;&lt;br /&gt;
# Skąd bierze się widoczna różnica w widmie sinusoidy 10 Hz i 10.3 Hz? &lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s,t) = sin(f = 10.3, T =1, Fs = 100, phi = 1)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s))&lt;br /&gt;
t_period = np.arange(0,3,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Długość sygnału a rozdzielczość widma FFT ====&lt;br /&gt;
Z dotychczasowych rozważań o transformacie Fouriera ograniczonych w czasie sygnałów dyskretnych wynika, że w widmie reprezentowane są częstości od &amp;lt;math&amp;gt;-F_N&amp;lt;/math&amp;gt; do &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; to częstości Nyquista. Dostępnych binów częstości jest ''N'' - tyle samo ile obserwowanych punktów sygnału. Zatem zwiększenie długości sygnału w czasie poprawia &amp;quot;rozdzielczość&amp;quot;  reprezentacji częstotliwościowej sygnału. &lt;br /&gt;
&lt;br /&gt;
Załóżmy, że dysponujemy jedynie sekwencją ''N'' próbek pewnego sygnału. Rozważymy teraz jakie można przyjąć strategie przedłużania tego sygnału w celu zwiększenia gęstości binów częstotliwościowych i jakie te strategie mają konsekwencje.&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Przedłużenie przez periodyczną replikację =====&lt;br /&gt;
Rozważając poprzednie przykłady zauważyliśmy, że FFT &amp;quot;widzi&amp;quot; sygnał tak jakby to była nieskończona periodyczna replikacja fragmentu sygnału podanego na wejście. Zatem najbardziej naturalną formą przedłużenia sygnału może wydawać się postępowanie zgodnie z tym sposobem widzenia i dołożenie do sygnału kolejnych segmentów zawierających kopie analizowanego fragmentu sygnału. Zbadajmy empirycznie efekty takiego podejścia. &lt;br /&gt;
&lt;br /&gt;
* Proszę wytworzyć i wykreślić sinusoidy o częstościach 15 i 20 Hz, trwające 0.1s i próbkowane 100Hz. &lt;br /&gt;
** Ile próbek sygnału dostajemy?&lt;br /&gt;
** Proszę obliczyć transformatę Fouriera. Ile punktów w widmie amplitudowym otrzymujemy? Dla jakich cżęstości mamy biny?&lt;br /&gt;
** Proszę skonstruować sygnał będący złożeniem 10 kopii oryginalnego sygnału. &lt;br /&gt;
Jest to 10-krotnie dłuższy fragment sygnału, którego wersję nieskończoną opisują współczynniki obliczone przez transformatę Fouriera. Transformata policzona z takiego wydłużonego odcinak ma 10-krotnie więcej binów. W szczególności zawiera on bin 15Hz. Proszę porównać wykresy widma amplitudowego otrzymanego dla wersji krótkiej i przedłużonej sygnału. Czy wynik jest zaskakujący? Jak go można zrozumieć?&lt;br /&gt;
 * Sygnał przedłużony periodycznie nie zawiera żadnej dodatkowej informacji względem pojedynczego okresu!&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s,s,s,s,s,s,s,s))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Przedłużanie sygnału zerami =====&lt;br /&gt;
Inną popularną metodą na zwiększanie ilości binów w transformacie Fouriera jest przedłużanie sygnału zerami (zero-padding). Jest to szczególny przypadek następującego podejścia: Nasz &amp;quot;prawdziwy&amp;quot; sygnał jest długi. Oglądamy go przez prostokątne okno, które ma wartość 1 na odcinku czasu dla którego próbki mamy dostępne i 0 dla pozostałego czasu (więcej o różnych oknach będzie na kolejnych zajęciach). W efekcie możemy myśleć, że oglądany przez nas sygnał to efekt przemnożenia &amp;quot;prawdziwego&amp;quot; sygnału przez okno. Efekty takiego przedłużania proszę zbadać przy użyciu poniższego kodu. &lt;br /&gt;
* Jak można zinterpretować wyniki tego eksperymentu w świetle [[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|twierdzenia o splocie]]?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,z,z,z,z,z,z,z,z,z))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S))&lt;br /&gt;
py.stem(F,np.abs(S)/len(S),linefmt='r-', markerfmt='ro')&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=Nieparametryczne_widmo_mocy&amp;diff=4259</id>
		<title>Nieparametryczne widmo mocy</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=Nieparametryczne_widmo_mocy&amp;diff=4259"/>
		<updated>2015-10-06T09:16:28Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Sygnały stochastyczne */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Widmo mocy==&lt;br /&gt;
=== Moc===&lt;br /&gt;
Moc chwilowa sygnału przez analogię do układów elektrycznych o jednostkowym oporze jest w analizie sygnałów przyjęta jako kwadraty próbek (&amp;lt;math&amp;gt;P = I^2 R = \frac{U^2}{R}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Oznaczmy sygnał &lt;br /&gt;
&amp;lt;math&amp;gt;x[n]&amp;lt;/math&amp;gt;, wówczas jego moc wyraża się wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;P[n]=x[n]^2&amp;lt;/math&amp;gt;, &lt;br /&gt;
a energia wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;E = \sum _n{x[n]^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
==== Zadanie ====&lt;br /&gt;
Przy pomocy funkcji napisanych na poprzednich zajęciach proszę wygenerować sygnał sinusoidalny o amplitudzie 1, częstości 10 Hz, trwający 0.3 sekundy i próbkowany z częstością 1000 Hz. Proszę narysować ten sygnał przy pomocy funkcji &amp;lt;tt&amp;gt;pylab.stem&amp;lt;/tt&amp;gt;, obliczyć i narysować przebieg mocy w czasie, obliczyć energię tego sygnału.&lt;br /&gt;
&lt;br /&gt;
===Widmo mocy: tw. Plancherela i tw. Parsevala ===&lt;br /&gt;
Twierdzenia te omawiane i dowodzone były na [[Szereg_Fouriera#To.C5.BCsamo.C5.9B.C4.87_Parsevala_dla_szereg.C3.B3w_Fouriera|wykładzie]]. Tutaj, tylko krótko przypomnijmy sobie: &lt;br /&gt;
====Twierdzenie Plancherela====&lt;br /&gt;
Jeśli &amp;lt;math&amp;gt;X[k]&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;Y[k]&amp;lt;/math&amp;gt; są transformatami &amp;lt;math&amp;gt;x[n]&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;y[n]&amp;lt;/math&amp;gt; odpowiednio to:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid15&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\sum _{n=0}^{N-1} x[n]y^*[n] = \frac{1}{N} \sum _{k=0}^{N-1} X[k] Y^*[k]&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
gwiazdka oznacza sorzężenie zespolone. &lt;br /&gt;
====Twierdzenie Parsevala====&lt;br /&gt;
jest specjalnym przypadkiem twierdzenia Plancherela:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid16&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\sum _{n=0}^{N-1} \left|x[n]\right|^2 = \frac{1}{N} \sum _{k=0}^{N-1} \left|X[k]\right|^2.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
Twierdzenie to upoważnia nas do utożsamiania kwadratów wartości bezwzględnej składowych transformaty Fouriera z mocą niesioną przez odpowiadające im składowe.&lt;br /&gt;
&lt;br /&gt;
=== Zadanie: funkcja do estymacji widma mocy ===&lt;br /&gt;
Proszę napisać i przetestować funkcję realizującą następujący algorytm estymacji widma mocy:&lt;br /&gt;
# Jako parametry funkcja przyjmuje sygnał &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; i częstość próbkowania tego sygnału&lt;br /&gt;
# Oblicz transformatę Fouriera sygnału przy pomocy &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Unormuj otrzymaną transformatę przez pierwiastek z ilości próbek sygnału&lt;br /&gt;
# Oblicz moc jako iloczyn unormowanej transformaty i jej sprzężenia zespolonego. W pythonie sprzężenie zespolone liczby &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; otrzymujemy korzystając z metody &amp;lt;tt&amp;gt;S.conj()&amp;lt;/tt&amp;gt;. W wyniku powyższego iloczynu dostaniemy liczby zespolone o zerowej części urojonej (proszę to sprawdzić). &lt;br /&gt;
# Do dalszych operacji wybierz tylko część rzeczywistą mocy. Część rzeczywistą liczby zespolonej M pobieramy w następujący sposób: &amp;lt;tt&amp;gt;czesc_rzeczywista_M = M.real&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Korzystając z funkcji &amp;lt;tt&amp;gt;fftfreq&amp;lt;/tt&amp;gt; obliczamy częstości, dla których policzone są współczynniki Fouriera.&lt;br /&gt;
# Przy pomocy funkcji &amp;lt;tt&amp;gt;fftshift&amp;lt;/tt&amp;gt; porządkujemy kolejność wektorów mocy i częstości, tak aby częstości były reprezentowane od -częstości Nyquista, przez 0, do +częstości Nyquista&lt;br /&gt;
# zwracamy uporządkowane wektory mocy i częstości&lt;br /&gt;
&lt;br /&gt;
Testowanie:&lt;br /&gt;
&lt;br /&gt;
# przy pomocy funkcji sin napisanej na drugich ćwiczeniach  wygeneruj sinusoidę o długości 1 s, o częstości 10Hz, próbkowaną 100 Hz.&lt;br /&gt;
# oblicz moc w czasie (trzeba podnieść wartość każdej próbki do kwadratu)&lt;br /&gt;
# oblicz moc w częstości przy pomocy funkcji estymacji widma mocy&lt;br /&gt;
# oblicz energię sygnału w czasie&lt;br /&gt;
# oblicz energię sygnału w częstości&lt;br /&gt;
# wykreśl: &lt;br /&gt;
#* sygnał&lt;br /&gt;
#* przebieg jego mocy w czasie&lt;br /&gt;
#* przebieg mocy w częstości&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import rfft,fft,fftfreq,fftshift&lt;br /&gt;
 &lt;br /&gt;
def widmo_mocy(s, Fs):&lt;br /&gt;
    S = fft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = S*S.conj()&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (fftshift(S_moc),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
(s,t) = sin(f=10,Fs=100.0)&lt;br /&gt;
moc_w_czasie = s**2&lt;br /&gt;
(moc_w_czestosci, F) = widmo_mocy(s, Fs=100.0)&lt;br /&gt;
&lt;br /&gt;
energia_w_czasie = np.sum(moc_w_czasie)&lt;br /&gt;
energia_w_czestosci = np.sum(moc_w_czestosci)&lt;br /&gt;
print 'energia w czasie: ', energia_w_czasie&lt;br /&gt;
print 'energia w czestosci: ', energia_w_czestosci&lt;br /&gt;
&lt;br /&gt;
py.subplot(3,1,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title('Sygnał')&lt;br /&gt;
py.subplot(3,1,2)&lt;br /&gt;
py.plot(t,moc_w_czasie)&lt;br /&gt;
py.title('moc w czasie')&lt;br /&gt;
py.subplot(3,1,3)&lt;br /&gt;
py.plot(F,moc_w_czestosci)&lt;br /&gt;
py.title('moc w częstości')&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===Rozdzielczość widma===&lt;br /&gt;
Proszę zbadać rozdzielczość częstotliwościową widma w zależności od długości sygnału. Używamy funkcji &amp;lt;tt&amp;gt;m_sin&amp;lt;/tt&amp;gt;. Zwrócić uwagę na to co dzieje się na końcach odcinka.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Okienkowanie a widmo mocy: periodogram===&lt;br /&gt;
Przypomnijmy wzór na dyskretną transformatę Fouriera [http://haar.zfb.fuw.edu.pl/edu/index.php/%C4%86wiczenia_2 DFT] zaimplementowaną w FFT: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;S[k] =  \sum_{n=0}^{n-1} s[n] \exp\left\{-2\pi i{nk \over N}\right\}       \qquad k = 0,\ldots,N-1.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Na podstawie twierdzenia [[Nieparametryczne_widmo_mocy#Twierdzenie_Parsevala|Parsevala]] możemy policzyć widmo mocy jako:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P[k] = \frac{1}{N}  \left|S[k]\right|^2 &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeśli do liczenia mocy chcielibyśmy posłużyć się techniką okiennkowania sygnału, to powinniśmy używać okienek znormalizowanych, czyli takich których energia jest równa 1, wtedy mnożenie przez okienko nie zaburzy estymaty energii sygnału. &lt;br /&gt;
&lt;br /&gt;
Aby policzyć widmo mocy sygnału z zastosowaniem okienek wprowadzimy następujące symbole:&lt;br /&gt;
* sygnał: &amp;lt;math&amp;gt;s[n]&amp;lt;/math&amp;gt;&lt;br /&gt;
* okienko: &amp;lt;math&amp;gt; w[n]&amp;lt;/math&amp;gt;&lt;br /&gt;
* okienko znormalizowane: &amp;lt;math&amp;gt; \hat w[n] = \frac{1}{\sqrt{\sum_{n=0}^{N-1} (w[n])^2}}w[n]&amp;lt;/math&amp;gt; &lt;br /&gt;
&amp;lt;!--(w szczególnym przypadku okienka prostokątnego normalizacja ta daje &amp;lt;math&amp;gt;1/N^2&amp;lt;/math&amp;gt; występujące we wzorze na moc)--&amp;gt;&lt;br /&gt;
* widmo mocy sygnału okienkowanego:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P[k] = \frac{1}{\sum_{n=0}^{N-1} (w[n])^2}  \left|\sum_{n=0}^{N-1} s[n]w[n] e^{i\frac{2 \pi }{N} k n}\right|^2 &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Zadanie ====&lt;br /&gt;
Proszę napisać funkcję obliczającą periodogram.&lt;br /&gt;
Funkcja jako argumenty powinna przyjmować sygnał, okno (podane jako sekwencja próbek), i częstość próbkowania. Zwracać powinna widmo mocy i skalę osi częstości. Wewnątrz funkcja powinna implementować liczenie widma z sygnału okienkowanego znormalizowanym oknem.&lt;br /&gt;
&lt;br /&gt;
Funkcję proszę przetestować obliczając dla funkcji sinus energię sygnału w dziedzinie czasu i w dziedzinie częstości. Testy proszę wykonać dla okna prostokątnego, Blackmana i Haminga.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , F_samp):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    F_samp- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 10.1, T =2, Fs = F_samp, phi = 0)&lt;br /&gt;
N = len(x) # dłogość sygnału&lt;br /&gt;
okno = np.ones(N)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N)&lt;br /&gt;
#okno = np.hamming(N)&lt;br /&gt;
&lt;br /&gt;
s = x*okno # sygnał okienkowany&lt;br /&gt;
#&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,x)&lt;br /&gt;
energia_t = np.sum(x**2)&lt;br /&gt;
print 'energia sygnału:', energia_t&lt;br /&gt;
py.title(u' sygnał')&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał')&lt;br /&gt;
py.title(u' sygnał okienkowany ')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
(S,F) = widmo_dB(s,N,F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego')&lt;br /&gt;
py.ylabel('dB')&lt;br /&gt;
&lt;br /&gt;
#periodogram&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
(P, F) = periodogram(x,okno,F_samp)&lt;br /&gt;
py.plot(F,P)&lt;br /&gt;
        &lt;br /&gt;
py.title('periodogram')&lt;br /&gt;
print 'energia periodogramu:', np.sum(P)&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Sygnały stochastyczne ==&lt;br /&gt;
Sygnał stochastyczny to taki sygnał, dla którego ciągu próbek nie da się opisać funkcją czasu. Kolejne próbki w takim sygnale to [[WnioskowanieStatystyczne/Zmienne_losowe_i_generatory_liczb_pseudolosowych#Zmienna_losowa|zmienne losowe]]. Można je opisać podając własności [[WnioskowanieStatystyczne/Zmienne_losowe_i_generatory_liczb_pseudolosowych#Rozk.C5.82ad_prawdopodobie.C5.84stwa|rozkładu]], z k†órego pochodzą. Często w opisie takich zmiennych posługujemy się [[WnioskowanieStatystyczne/Zmienne_losowe_i_generatory_liczb_pseudolosowych#Momenty|momentami rozkładów]].&lt;br /&gt;
Jak można sobie wyobrazić rozkłady, z których pochodzą próbki?&lt;br /&gt;
Można sobie wyobrazić,że obserwowany przez nas sygnał stochastyczny to jedna z możliwych realizacji procesu stochastycznego. &lt;br /&gt;
Jeśli &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; jest zbiorem &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; zdarzeń (&amp;lt;math&amp;gt;k \in K&amp;lt;/math&amp;gt;) i każde z tych zdarzeń ma przypisaną funkcję &amp;lt;math&amp;gt;x_k(t)&amp;lt;/math&amp;gt; zwaną realizacją procesu &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt;, to proces stochastyczny może być zdefiniowany jako zbiór funkcji:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid23&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\xi (t) = \left\lbrace x_1(t),x_2(t),\dots , x_N(t) \right\rbrace &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;x_k(t)&amp;lt;/math&amp;gt; są losowymi funkcjami czasu &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Procesy stochastyczne można opisywać prze wartości oczekiwane liczone po realizacjach.&lt;br /&gt;
&lt;br /&gt;
Dla przypomnienia wartość oczekiwaną liczymy tak:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid24&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
{\mu _x(t_1) = E\left[\xi (t_1) \right]= \lim _{N \rightarrow \infty }\sum _{k=1}^{N}{x_k(t_1)} p(x_k,t_1)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
średnia &amp;lt;math&amp;gt;\mu _x(t_1)&amp;lt;/math&amp;gt; procesu &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt; w chwili &amp;lt;math&amp;gt;t_1&amp;lt;/math&amp;gt; to suma wartośći zaobserwowanych w chwili we wszystkich realizacjach &amp;lt;math&amp;gt;t_1&amp;lt;/math&amp;gt; ważona prawdopodobieństwem wystąpienia tej realizacji:&lt;br /&gt;
=== Stacjonarność i ergodyczność===&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
	&amp;lt;dt&amp;gt;&lt;br /&gt;
	Stacjonarność:&lt;br /&gt;
	&amp;lt;dd&amp;gt;&lt;br /&gt;
	Jeśli dla procesu stochastycznego &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt; wszystkie momenty są niezależne od czasu to jest on stajonarny w ścisłym sensie. Jeśli tylko średnia &amp;lt;math&amp;gt;\mu _x&amp;lt;/math&amp;gt; i autokorelacja &amp;lt;math&amp;gt;R_x(\tau )&amp;lt;/math&amp;gt; nie zależą od czasu to proces jest stacjonarny w słabym sensie, co dla wielu zastosowań jest wystarczające.&lt;br /&gt;
	&amp;lt;dt&amp;gt;&lt;br /&gt;
	Ergodyczność:&lt;br /&gt;
	&amp;lt;dd&amp;gt;&lt;br /&gt;
	Proces jest ergodyczny jeśli jego średnie po czasie i po realizacjach są sobie równe. Oznacza to, że dla takiego procesu jedna realizacja jest reprezentatywna i zawiera całą informację o tym procesie.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Założenie o sygnale, że jest stacjonarny i ergodyczny pozwala zamienić sumowanie po realizacjach na sumowanie po czasie w estymatory momentów statystycznych.&lt;br /&gt;
&lt;br /&gt;
===Transformata Fouriera sygnału stochastycznego===&lt;br /&gt;
Bardzo często musimy oszacować widmo mocy sygnału zawierającego znaczny udział szumu.&lt;br /&gt;
&lt;br /&gt;
Poniższe ćwiczenie ilustruje niepewność szacowania pików w widmie otrzymanym z transformaty Fouriera dla sygnału zawierającego szum.&lt;br /&gt;
&lt;br /&gt;
* wygeneruj 20 realizacji sygnału będącego sumą sinusoidy (f = 20 Hz, T = 1 s, Fs = 100 Hz) i  szumu gaussowskiego&lt;br /&gt;
* dla każdej realizacji oblicz widmo mocy&lt;br /&gt;
* wykreśl wszystkie otrzymane widma na wspólnym wykresie&lt;br /&gt;
&lt;br /&gt;
Proszę obejrzeć otrzymane widma.&lt;br /&gt;
* Zaobserwuj jakiego rzędu jest niepewność wyniku.&lt;br /&gt;
* Czy podobny problem występuje dla sygnału bez szumu?&lt;br /&gt;
* Skonstruuj funkcję rysującą średnie widmo wraz z [[WnioskowanieStatystyczne/_Przedzia%C5%82y_ufno%C5%9Bci|przedziałem ufności]].&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import scipy.stats as st&lt;br /&gt;
&lt;br /&gt;
from numpy.fft import rfft,fft,fftfreq,fftshift&lt;br /&gt;
 &lt;br /&gt;
def widmo_mocy(s, Fs):&lt;br /&gt;
    '''funkcja oblicza widmo mocy sygnału i oś częstości&lt;br /&gt;
    s - sygnał&lt;br /&gt;
    Fs - częstość próbkowania&lt;br /&gt;
    '''&lt;br /&gt;
    S = fft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = S*S.conj()&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (fftshift(S_moc),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def widmo_mocy_rzeczywistego(s,FS):&lt;br /&gt;
    '''funkcja oblicza widmo mocy sygnału rzeczywistego i oś częstości&lt;br /&gt;
    s - sygnał&lt;br /&gt;
    Fs - częstość próbkowania&lt;br /&gt;
&lt;br /&gt;
    zwraca dodatnią część widma&lt;br /&gt;
    '''&lt;br /&gt;
    S = rfft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = np.abs(S)**2&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (S_moc,F)&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def szum(mu =0 , sigma = 1, T = 1, Fs = 128):&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.random.randn(len(t) )*sigma + mu&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def dwadziescia_realizacji(FS):&lt;br /&gt;
    '''&lt;br /&gt;
    *  wygeneruj 20 realizacji sygnału będącego sumą sinusoidy (f=20Hz, T=1s, Fs =100Hz) i szumu gassowskiego&lt;br /&gt;
    * dla każdej realizacji oblicz widmo mocy&lt;br /&gt;
    * wykreśl wszystkie otrzymane widma na wspólnym wykresie &lt;br /&gt;
    '''&lt;br /&gt;
    for i in range(20):&lt;br /&gt;
        (s,t) = sin(f=10,Fs=FS)&lt;br /&gt;
        (sz,t) = szum(Fs =FS)&lt;br /&gt;
        syg = s + sz&lt;br /&gt;
        (moc_w_czestosci, F) = widmo_mocy(syg, Fs=FS)&lt;br /&gt;
        py.plot(F,moc_w_czestosci)&lt;br /&gt;
    py.show()&lt;br /&gt;
    &lt;br /&gt;
def srednie_widmo(FS):&lt;br /&gt;
    '''&lt;br /&gt;
    #  Skonstruuj funkcję rysującą średnie widmo wraz z 95% przedziałem ufności. &lt;br /&gt;
    '''&lt;br /&gt;
    zbior_widm = np.zeros((20,FS))&lt;br /&gt;
    for i in range(20):&lt;br /&gt;
        (s,t) = sin(f=10,Fs=FS)&lt;br /&gt;
        (sz,t) = szum(Fs =FS)&lt;br /&gt;
        syg = s + sz&lt;br /&gt;
        (moc_w_czestosci, F) = widmo_mocy(syg, Fs=FS)&lt;br /&gt;
        zbior_widm[i][:] = moc_w_czestosci&lt;br /&gt;
    srednie_w = np.mean(zbior_widm,axis =0)&lt;br /&gt;
    przedzial_d = np.zeros(len(F))&lt;br /&gt;
    przedzial_g = np.zeros(len(F))&lt;br /&gt;
    for f in F:&lt;br /&gt;
        przedzial_d[f] = st.scoreatpercentile(zbior_widm[:,f], 2.5)&lt;br /&gt;
        przedzial_g[f] = st.scoreatpercentile(zbior_widm[:,f], 97.5)&lt;br /&gt;
    py.plot(F,srednie_w,'r')&lt;br /&gt;
    py.plot(F,przedzial_d,'b')&lt;br /&gt;
    py.plot(F,przedzial_g,'b')&lt;br /&gt;
    py.show()&lt;br /&gt;
&lt;br /&gt;
FS =100.0    &lt;br /&gt;
#dwadziescia_realizacji(FS)&lt;br /&gt;
srednie_widmo(FS)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Oszacowanie błędu transformaty Fouriera dla białego szumu ===&lt;br /&gt;
Dla sygnału stochastycznego &amp;lt;math&amp;gt;x(t)&amp;lt;/math&amp;gt;, którego kolejne próbki pochodzą z niezależnych rozkładów normalnych (biały szum), jego transformata Fouriera &amp;lt;math&amp;gt;X(f)&amp;lt;/math&amp;gt; jest liczbą zespoloną, której część rzeczywista &amp;lt;math&amp;gt;X_R(f)&amp;lt;/math&amp;gt; i urojona &amp;lt;math&amp;gt;X_I(f)&amp;lt;/math&amp;gt; mogą być uznane za nieskorelowane zmienne losowe o średniej zero i równych wariancjach. Ponieważ transformata Fouriera jest operacją liniową więc składowe  &amp;lt;math&amp;gt;X_R(f)&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;X_I(f)&amp;lt;/math&amp;gt; mają rozkłady normalne. Zatem wielkość:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P(f) = |X(f)|^2 = X_R^2(f) + X_I^2(f)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
jest sumą kwadratów dwóch niezależnych zmiennych normalnych. Wielkość ta podlega zatem rozkładowi &amp;lt;math&amp;gt;\chi^2&amp;lt;/math&amp;gt; o dwóch stopniach swobody.&lt;br /&gt;
Możemy oszacować względny błąd &amp;lt;math&amp;gt;P(f_1) &amp;lt;/math&amp;gt; dla danej częstości &amp;lt;math&amp;gt;f_1&amp;lt;/math&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\epsilon_r= \sigma_{P_{f_1}}/\mu_{P_{f_1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dla rozkładu &amp;lt;math&amp;gt;\chi_2^2&amp;lt;/math&amp;gt;:  &amp;lt;math&amp;gt;\sigma^2 = 2n&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;\mu = n&amp;lt;/math&amp;gt;, gdzie &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; jest ilością stopni swobody. W naszym przypadku &amp;lt;math&amp;gt;n =2&amp;lt;/math&amp;gt; więc mamy &amp;lt;math&amp;gt;\epsilon_f = 1&amp;lt;/math&amp;gt;, co oznacza, że dla pojedynczego binu częstości w widmie &amp;lt;math&amp;gt;P(f)&amp;lt;/math&amp;gt; względny błąd wynosi 100%. &lt;br /&gt;
&lt;br /&gt;
Aby zmniejszyć ten błąd trzeba zwiększyć ilość stopni swobody. Są generalnie stosowane dwie techniki. Pierwsza to uśrednianie sąsiednich binów częstości. Otrzymujemy wówczas wygładzony estymator mocy &amp;lt;math&amp;gt;\hat{P}_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\hat{P}_k = \frac{1}{l}[P_k + P_{k+1} + \dots + P_{k+l-1}]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zakładając, że biny częstości  &amp;lt;math&amp;gt;P_i&amp;lt;/math&amp;gt; są niezależne estymator &amp;lt;math&amp;gt;P_k&amp;lt;/math&amp;gt; ma rozkład &amp;lt;math&amp;gt;\chi^2&amp;lt;/math&amp;gt; o ilości stopni swobody równej &amp;lt;math&amp;gt;n= 2l&amp;lt;/math&amp;gt;. Względny błąd takiego estymatora to: &amp;lt;math&amp;gt;\epsilon_r= \sqrt{\frac{1}{l}}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Innym sposobem poprawy estymatora mocy jest podzielenie sygnału na fragmenty, obliczenie periodogramu dla każdego fragmentu, a następnie zsumowanie otrzymanych wartości:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\hat{P}_k=[P_{k,1}+P_{k,2}+\dots+P_{k,j}+\dots+P_{k,q}]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;S_{k,j}&amp;lt;/math&amp;gt; jest estymatą składowej o częstości &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; w oparciu o &amp;lt;math&amp;gt;j-ty&amp;lt;/math&amp;gt; fragment sygnału. Ilość stopni swobody wynosi w tym przypadku &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; zatem względny błąd wynosi: &amp;lt;math&amp;gt;\epsilon_r = \sqrt{\frac{1}{q}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Zauważmy, że w obu metodach zmniejszamy wariancję estymatora kosztem rozdzielczości w częstości.&lt;br /&gt;
&lt;br /&gt;
===Metoda Welcha===&lt;br /&gt;
Proszę napisać i przetestować funkcję implementującą metodę Welcha estymacji widma mocy. Algorytm Welcha:&lt;br /&gt;
# sygnał &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; o długości ''N'' jest dzielony na segmenty, każdy o długości &amp;lt;math&amp;gt;N_s&amp;lt;/math&amp;gt;. Odcinki mogą na siebie zachodzić na &amp;lt;math&amp;gt;N_z&amp;lt;/math&amp;gt; punktów. Czyli są względem siebie przesunięte o &amp;lt;math&amp;gt;N_p = N_s-N_z&amp;lt;/math&amp;gt;.&lt;br /&gt;
# z każdego segmentu liczony jest okienkowany periodogram&lt;br /&gt;
# periodogramy są sumowane&lt;br /&gt;
# wynik dzielony jest przez efektywne wykorzystanie każdego kawałka sygnału w estymacie: &amp;lt;tt&amp;gt;K_eff = dlogosc_okna * ilosc_okien / dlugosc_sygnalu&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funkcję proszę przetestować obliczając dla funkcji sinus energię sygnału w dziedzinie czasu i w dziedzinie częstości. Testy proszę wykonać dla okna prostokątnego, Blackmana i Haminga. &lt;br /&gt;
&lt;br /&gt;
 * &amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
def pwelch(s,okienko, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okienko)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,F_samp)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Całość razem z kodem testującym:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , Fs):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    Fs- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
def pwelch(s,okienko, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okienko)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,Fs)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 3.1, T =20, Fs = F_samp, phi = 0)&lt;br /&gt;
N = len(x) # dłogość sygnału&lt;br /&gt;
&lt;br /&gt;
okno = np.ones(N)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N)&lt;br /&gt;
#okno = np.hamming(N)&lt;br /&gt;
&lt;br /&gt;
s = x*okno # sygnał okienkowany&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
(P, F) = periodogram(x,okno,F_samp)&lt;br /&gt;
py.plot(F,P) &lt;br /&gt;
py.title('periodogram'+' energia: '+ str(np.sum(P)))&lt;br /&gt;
&lt;br /&gt;
#periodogram&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
N_s = N/8&lt;br /&gt;
#okno = np.ones(N_s)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N_s)&lt;br /&gt;
okno = np.hamming(N_s)&lt;br /&gt;
&lt;br /&gt;
         &lt;br /&gt;
(P, F) = pwelch(x,okno,N_s/10,F_samp)&lt;br /&gt;
py.plot(F,P)&lt;br /&gt;
py.title('periodogram Welcha'+' energia: '+ str(np.sum(P)))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Porównanie rozdzielczości i wariancji w periodogramie i w estymatorze Welcha===&lt;br /&gt;
#  wygeneruj 100 realizacji sygnału będącego sumą sinusoidy (f = 20 Hz, T = 10 s, Fs = 100 Hz) i szumu gaussowskiego&lt;br /&gt;
# dla każdej realizacji oblicz widmo mocy za pomocą periodogramu okienkowanego oknem Blackmana&lt;br /&gt;
# wykreśl wszystkie otrzymane widma na wspólnym wykresie (subplot(2,1,1))&lt;br /&gt;
# Powtórz krok 2) dla estymatora Welcha z oknem Blackmana o długości 1/10 długości sygnału przesuwanym co 2 punkty, otrzymane widma wykreśl  na wspólnym wykresie (subplot(2,1,2))&lt;br /&gt;
&lt;br /&gt;
* Co można powiedzieć o rozdzielczości i względnym błędzie obu metod?&lt;br /&gt;
&amp;lt;tt&amp;gt;bl_wzg = np.std(S,axis = 0)/np.mean(S,axis = 0)&amp;lt;/tt&amp;gt; gdzie S jest tablicą zawierającą widma dla każdej z realizacji.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , Fs):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    Fs- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/Fs)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
def pwelch(s,okno, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okno)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,Fs)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&lt;br /&gt;
def realizacja(T,Fs):&lt;br /&gt;
    (x,t) = sin(f = 20.0, T = T, Fs = Fs, phi = 0)&lt;br /&gt;
    x += 2*np.random.randn(len(x))&lt;br /&gt;
    return x&lt;br /&gt;
&lt;br /&gt;
T=10.0&lt;br /&gt;
Fs = 100.0&lt;br /&gt;
N = T*Fs&lt;br /&gt;
Nw = N/10.0&lt;br /&gt;
okno = np.blackman(N)&lt;br /&gt;
okno_welch = np.blackman(Nw)&lt;br /&gt;
&lt;br /&gt;
N_rep = 100&lt;br /&gt;
S_perio = np.zeros((N_rep,N))&lt;br /&gt;
S_welch = np.zeros((N_rep,Nw))&lt;br /&gt;
py.figure(1)&lt;br /&gt;
for i in range(N_rep):&lt;br /&gt;
    s = realizacja(T,Fs)&lt;br /&gt;
    (P, F) = periodogram(s,okno,Fs) &lt;br /&gt;
    S_perio[i] = P&lt;br /&gt;
    py.subplot(2,1,1)&lt;br /&gt;
    py.plot(F,P) &lt;br /&gt;
    (P, F) = pwelch(s,okno_welch,Nw/10,Fs)&lt;br /&gt;
    S_welch[i] = P&lt;br /&gt;
    py.subplot(2,1,2)&lt;br /&gt;
    py.plot(F,P)&lt;br /&gt;
&lt;br /&gt;
py.figure(2)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(np.std(S_perio,axis = 0)/np.mean(S_perio,axis = 0))&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.std(S_welch,axis = 0)/np.mean(S_welch,axis = 0))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===Wielookienkowa metoda Thomsona===&lt;br /&gt;
Metoda ta &lt;br /&gt;
[http://ieeexplore.ieee.org/Xplore/login.jsp?url=http%3A%2F%2Fieeexplore.ieee.org%2Fiel5%2F5%2F31317%2F01456701.pdf%3Farnumber%3D1456701&amp;amp;authDecision=-201 Spectrum estimation and harmonic analysis] &lt;br /&gt;
znana jest pod anglojęzyczną nazwą  ''multitaper''. &lt;br /&gt;
&lt;br /&gt;
Można ją opisać poniższym algorytmem:&lt;br /&gt;
* wygeneruj sekwencję ortogonalnych okienek charakteryzujących się minimalnymi wyciekami widma (stosunek energii w piku centralnym do energii w listkach bocznych jest wysoki). Sekwencja takich okien nazywana jest discrete prolate spheroidal sequences (DPSS) lub sekwencją Slepiana.&lt;br /&gt;
* oblicz widmo sygnału okienkowanego każdym z okien w sekwencji&lt;br /&gt;
* uśrednij otrzymane widma&lt;br /&gt;
&lt;br /&gt;
Kolejne dwa zadania służą zapoznaniu się z tą metodą.&lt;br /&gt;
====Własności okienek DPSS ====&lt;br /&gt;
Do generacji sekwencji okienek DPSS wykorzystamy moduł [http://brain.fuw.edu.pl/edu-wiki/images/f/f6/Gendpss.py Gendpss.py]. Proszę go zapisać w swoim katalogu roboczym. &lt;br /&gt;
Importujemy go do naszych programów tak jak każdy inny moduł np.:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import Gendpss as dpss&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Funkcja potrzebna nam z tego modułu to &amp;lt;tt&amp;gt;gendpss()&amp;lt;/tt&amp;gt;. Funkcja ta wytwarza obiekt reprezentujący konkretną sekwencję DPSS. Wywołujemy ją następująco:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
w = dpss.gendpss(N,NW,K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:gdzie: N: długość okna,&lt;br /&gt;
:        NW: iloczyn czas-szerokość pasma&lt;br /&gt;
:        K: ile okien w sekwencji&lt;br /&gt;
Po powyższym wywołaniu obiekt &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; posiada dwie interesujące nas tablice:&lt;br /&gt;
* &amp;lt;tt&amp;gt;w.lambdas&amp;lt;/tt&amp;gt; - to wartości własne okienek. Są one miarą koncentracji energii w piku głównym, jest to zatem miara jakości okienka (dobre okienka mają wartości własne bliskie 1). Zgodnie z teorią takich wartości powinno być 2*NW-1.&lt;br /&gt;
* &amp;lt;tt&amp;gt;w.dpssarray[i]&amp;lt;/tt&amp;gt; - i-te okienko.&lt;br /&gt;
&lt;br /&gt;
=====Polecenia:=====&lt;br /&gt;
Proszę:&lt;br /&gt;
* wygenerować okienka o długości 256, NW = 2. Ilość okien K raz ustalić na 3 (2*NW-1) a drugi raz na 5. Dla ilu okienek ich wartości własne są bliskie 1?&lt;br /&gt;
* narysować przebieg czasowy okienek&lt;br /&gt;
* sprawdzić czy energia okienek jest znormalizowana do 1.&lt;br /&gt;
* sprawdzić czy kolejne okienka są do siebie ortogonalne. W tym celu należy obliczyć iloczyn skalarny pomiędzy kolejnymi okienkami (np.sum(w.dpssarray[i]*w.dpssarray[j])). &lt;br /&gt;
* wyrysować widma okienek analogicznie jak [[%C4%86wiczenia_3#Badanie_w.C5.82asno.C5.9Bci_okien|w tym ćwiczeniu]]&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import gendpss as dpss&lt;br /&gt;
from numpy.fft import fft,fftshift,fftfreq&lt;br /&gt;
&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1.0/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NW = 2&lt;br /&gt;
ile_okien = 5#2*NW-1&lt;br /&gt;
N_okna = 256&lt;br /&gt;
w = dpss.gendpss(N=N_okna,NW=NW,K=ile_okien)&lt;br /&gt;
print 'Wartości własne:'&lt;br /&gt;
print w.lambdas&lt;br /&gt;
&lt;br /&gt;
print 'Wartości iloczynów skalarnych pomiędzy kolejnymi okienekami:'&lt;br /&gt;
py.figure(1)&lt;br /&gt;
for i in range(ile_okien):&lt;br /&gt;
    py.plot(w.dpssarray[i])&lt;br /&gt;
    for j in range(i+1):&lt;br /&gt;
        print np.sum(w.dpssarray[i]*w.dpssarray[j]),&lt;br /&gt;
    print&lt;br /&gt;
&lt;br /&gt;
py.figure(2)&lt;br /&gt;
NFFT = N_okna*4&lt;br /&gt;
S=np.zeros((ile_okien,NFFT))&lt;br /&gt;
for i in range(ile_okien):&lt;br /&gt;
    py.subplot(ile_okien,1,i+1)&lt;br /&gt;
    (S_db, F)= widmo_dB(w.dpssarray[i], NFFT, 1.0)&lt;br /&gt;
    S[i,:]=S_db&lt;br /&gt;
    py.plot(F,S_db)&lt;br /&gt;
    py.ylim((-200,20))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Estymacja widma mocy metodą multitaper ====&lt;br /&gt;
Proszę napisać funkcję do estymacji mocy metodą multitaper.&lt;br /&gt;
Funkcja powinna pobierać następujące argumenty: sygnał, iloczyn NW, częstość próbkowania sygnału. Funkcja powinna zwracać krotkę &amp;lt;tt&amp;gt;(S,F)&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; widmo mocy, &amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt; skala częstości.&lt;br /&gt;
Przykładowe wywołanie takiej funkcji powinno wyglądać tak:&lt;br /&gt;
&amp;lt;tt&amp;gt; (S,F) = mtm(s,  NW = 3, Fs = 128)&amp;lt;/tt&amp;gt;&lt;br /&gt;
Algorytm do zastosowania wewnątrz funkcji:&lt;br /&gt;
# Oblicz maksymalną liczbę okienek &amp;lt;tt&amp;gt; K = 2*NW-1&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Oblicz długość sygnału&lt;br /&gt;
# wygeneruj serię okienek dpss&lt;br /&gt;
# dla każdego z otrzymanych okienek oblicz widmo mocy iloczynu tego okienka i sygnału. Dla i-tego okienka będzie to: &amp;lt;tt&amp;gt;Si = np.abs(fft(s*w.dpssarray[i]))**2&amp;lt;/tt&amp;gt;&lt;br /&gt;
# uśrednij widma otrzymane dla wszystkich okienek&lt;br /&gt;
# wygeneruj oś częstości (&amp;lt;tt&amp;gt;fftfreq&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Działanie funkcji sprawdź estymując i wykreślając widmo sinusoidy np. o częstości 10 Hz, czasie trwania 1s, próbkowanej 100Hz z dodanym szumem gaussowskim o średniej 0 i wariancji 1. Sprawdź także zachowanie energii przez tą estymatę. Dla porównania na tym samym wykresie dorysuj widmo otrzymane przez [[Nieparametryczne_widmo_mocy#Okienkowanie_a_widmo_mocy:_periodogram|periodogram]] z oknem prostokątnym.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import gendpss as dpss&lt;br /&gt;
from numpy.fft import fft,fftshift,fftfreq&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def mtm(s, NW = 3, Fs = 128):&lt;br /&gt;
    '''estymacja widma w oparciu o  metodę Multiteper &lt;br /&gt;
    D. J. Thomson, “Spectrum Estimation and Harmonic Analysis,” Proceedings of the&lt;br /&gt;
    IEEE, vol. 70, no. 9, pp. 1055 – 1096, 1982.&lt;br /&gt;
    x - sygnał&lt;br /&gt;
    N -ilość punktów okna&lt;br /&gt;
    NW - iloczyn długości okna w czasie i szerokości w częstości&lt;br /&gt;
    K - ilość okien&lt;br /&gt;
&lt;br /&gt;
    funkcja zwraca estymatę mocy widmowej&lt;br /&gt;
    '''&lt;br /&gt;
    K = 2*NW-1&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    w = dpss.gendpss(N,NW,K)&lt;br /&gt;
    S=np.zeros(N)&lt;br /&gt;
    for i in range(K):&lt;br /&gt;
        Si = np.abs(fft(s*w.dpssarray[i]))**2&lt;br /&gt;
        S[:] += Si.real&lt;br /&gt;
    S = S/K&lt;br /&gt;
    F = fftfreq(N,1.0/Fs)&lt;br /&gt;
    return (fftshift(S),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fs = 100.0&lt;br /&gt;
NW = 3&lt;br /&gt;
(s,t) = sin(f=10.2,Fs=Fs)&lt;br /&gt;
s = s+np.random.randn(len(s))&lt;br /&gt;
(S,F) = mtm(s, NW = NW,  Fs = Fs)&lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.plot( F,fftshift(np.abs(fft(s))**2/len(s) ) ,'g')&lt;br /&gt;
&lt;br /&gt;
print np.sum(S)&lt;br /&gt;
print np.sum(s**2)&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_7&amp;diff=4258</id>
		<title>Ćwiczenia 7</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_7&amp;diff=4258"/>
		<updated>2015-10-06T09:11:36Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Zadania */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Filtry IIR==&lt;br /&gt;
&lt;br /&gt;
Filtry o nieskończonej odpowiedzi impulsowej (''infinite impulse response'', IIR) mają zazwyczaj dużo niższe rzędy niż filtry o skończonej odpowiedzi impulsowej (''finite impulse response'', FIR) z analogicznym poziomem tłumienia i szerokością pasma przejściowego.&lt;br /&gt;
&lt;br /&gt;
W module &amp;lt;tt&amp;gt;scipy.signal&amp;lt;/tt&amp;gt; mamy zaimplementowane kilka funkcji do projektowania &amp;amp;bdquo;optymalnych&amp;amp;rdquo; pod różnymi względami filtrów w klasycznych konfiguracjach:&lt;br /&gt;
dolno- albo górnoprzepustowe i pasmowo-przepustowe albo pasmowo-zaporowe.&lt;br /&gt;
&lt;br /&gt;
==Funkcje do projektowania filtrów IIR dostępne w module &amp;lt;tt&amp;gt;scipy.signal&amp;lt;/tt&amp;gt;==&lt;br /&gt;
W module &amp;lt;tt&amp;gt;scipy.signal&amp;lt;/tt&amp;gt; dostępne są funkcje do projektowania czterech typów filtrów: Butterwortha, Czebyszewa typu I i II, oraz eliptyczny.&lt;br /&gt;
Do opisu wymagań projektowych funkcje te wykorzystują następujące pojęcia:&lt;br /&gt;
* &amp;lt;tt&amp;gt;wp&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;ws&amp;lt;/tt&amp;gt; &amp;amp;mdash; krawędzie pasma przenoszenia i tłumienia. Częstości są znormalizowane do zakresu od 0 do 1 (1 odpowiada częstości Nyquista) przykładowo:&lt;br /&gt;
** dolno-przepustowy:  &amp;lt;tt&amp;gt;wp = 0.2&amp;lt;/tt&amp;gt;,          &amp;lt;tt&amp;gt;ws = 0.3&amp;lt;/tt&amp;gt;&lt;br /&gt;
** górno-przepustowy:  &amp;lt;tt&amp;gt;wp = 0.3&amp;lt;/tt&amp;gt;,          &amp;lt;tt&amp;gt;ws = 0.2&amp;lt;/tt&amp;gt;&lt;br /&gt;
** pasmowo-przepustowy:  &amp;lt;tt&amp;gt;wp = [0.2, 0.5]&amp;lt;/tt&amp;gt;,   &amp;lt;tt&amp;gt;ws = [0.1, 0.6]&amp;lt;/tt&amp;gt;&lt;br /&gt;
** pasmowo-zaporowy:  &amp;lt;tt&amp;gt;wp = [0.1, 0.6]&amp;lt;/tt&amp;gt;,   &amp;lt;tt&amp;gt;ws = [0.2, 0.5]&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;gpass&amp;lt;/tt&amp;gt; &amp;amp;mdash; maksymalna dopuszczalna strata w pasmie przenoszenia (w funkcjach projektujących filtry jest to &amp;lt;tt&amp;gt;rp&amp;lt;/tt&amp;gt;) (dB).&lt;br /&gt;
* &amp;lt;tt&amp;gt;gstop&amp;lt;/tt&amp;gt; &amp;amp;mdash; minimalne wymagane tłumienie w pasmie tłumienia (w funkcjach projektujących filtry jest to &amp;lt;tt&amp;gt;rs&amp;lt;/tt&amp;gt;) (dB).&lt;br /&gt;
* &amp;lt;tt&amp;gt;btype&amp;lt;/tt&amp;gt; &amp;amp;mdash; typ filtra (&amp;lt;tt&amp;gt;'lowpass'&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;'highpass'&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;'bandpass'&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;'bandstop'&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Funkcje do projektowania filtrów są zaimplementowane parami: jedna pomaga dobierać rząd filtru do wymagań projektowych, a druga oblicza współczynniki filtru. &lt;br /&gt;
&lt;br /&gt;
'''Filtr Butterwortha'''&lt;br /&gt;
daje gładką (bez tętnień) funkcję przenoszenia w całym zakresie częstości&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
[n,Wn]=buttord(wp, ws, gpass, gstop, analog=0)&lt;br /&gt;
[b,a]=butter(n,Wn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; &amp;amp;mdash; rząd filtra, &amp;lt;tt&amp;gt;Wn&amp;lt;/tt&amp;gt; &amp;amp;mdash; krawędzie pasm&lt;br /&gt;
&lt;br /&gt;
'''Filtr Czebyszewa I rodzaju''' &amp;amp;mdash; gładka funkcja przenoszenia w paśmie tłumienia, minimalizowane są tętnienia  w paśmie przenoszenia&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
[n,Wn]=cheb1ord(wp, ws, gpass, gstop, analog=0);&lt;br /&gt;
[b,a]=cheby1(n, rp, Wn, btype='low', analog=0, output='ba')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Filtr Czebyszewa II''' rodzaju &amp;amp;mdash; gładka funkcja przenoszenia w paśmie przenoszenia, minimalizowane tętnienia w paśmie tłumienia&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
[n,Wn]=cheb2ord(wp, ws, gpass, gstop, analog=0);&lt;br /&gt;
[b,a]=cheby2(n, rs, Wn, btype='low', analog=0, output='ba')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Filtr eliptyczny''' daje najostrzejsze przejście pomiędzy pasmem tłumienia i przenoszenia przy tym samym rzędzie w porównaniu z wyżej wymienionymi filtrami, tętnienia są obecne zarówno w paśmie przenoszenia jak i w paśmie tłumienia&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
[n,Wn]=ellipord(Wp, Ws, Rp,Rs);&lt;br /&gt;
[b,a]=ellip(n, rp, rs, Wn, btype='low', analog=0, output='ba')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Filtrowanie z zerowym przesunięciem fazowym==&lt;br /&gt;
&lt;br /&gt;
Filtrowanie sygnałów off-line można zrealizować tak, aby sygnał wyjściowy nie miał przesunięcia fazowego. Metodę tę zaprezentujemy na poniższym przykładzie. Rozważymy co dzieje się z pojedynczą składową fourierowską sygnału o częstości &amp;lt;math&amp;gt;\omega&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Niech ta składowa nazywa się &lt;br /&gt;
:&amp;lt;math&amp;gt;s_{\omega} (t) = A_{\omega} e^{i \omega t} &amp;lt;/math&amp;gt;, &lt;br /&gt;
:natomiast transmitancja filtru dla częstości &lt;br /&gt;
:&amp;lt;math&amp;gt;H(\omega) = |H_{\omega}| e^{i \phi_{\omega}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Podając tę składową na wejście filtru, na jego wyjściu otrzymujemy &amp;lt;math&amp;gt;s^'_{\omega}(t)&amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt;s^'_{\omega}(t) = A_{\omega}|H_{\omega}| e^{i \omega t}e^{i \phi_{\omega}} &amp;lt;/math&amp;gt;&lt;br /&gt;
* korzystając z definicji przesunięcia fazowego możemy to zapisać:&lt;br /&gt;
:&amp;lt;math&amp;gt;s^'_{\omega}(t) = A_{\omega}|H_{\omega}| e^{i \omega( t- \tau_{\omega})} &amp;lt;/math&amp;gt;&lt;br /&gt;
* w sygnale tym odwracamy sekwencję czasową (kierunek czasu):&lt;br /&gt;
:&amp;lt;math&amp;gt;s^{''}_{\omega}(t) =s^{'}_{\omega}(-t) = A_{\omega}|H_{\omega}| e^{-i \omega( t- \tau_{\omega})} &amp;lt;/math&amp;gt;&lt;br /&gt;
* otrzymany sygnał podajemy na wejście filtru, wówczas na wyjściu pojawi się następujący sygnał:&lt;br /&gt;
:&amp;lt;math&amp;gt;s^{'''}_{\omega}(t) = A_{\omega}|H_{\omega}||H_{\omega}| e^{-i \omega( t- \tau_{\omega})}e^{i \phi_{\omega}} &amp;lt;/math&amp;gt;&lt;br /&gt;
* ponownie korzystając z definicji przesunięcia fazowego możemy napisać:&lt;br /&gt;
:&amp;lt;math&amp;gt;s^{'''}_{\omega}(t) = A_{\omega}|H_{\omega}|^2 e^{-i \omega t + \omega\tau_{\omega}- \omega\tau_{\omega}}= A_{\omega}|H_{\omega}|^2 e^{-i \omega t } &amp;lt;/math&amp;gt; &lt;br /&gt;
* w tym sygnale ponownie odwracamy sekwencję czasową i otrzymujemy:&lt;br /&gt;
:&amp;lt;math&amp;gt;y(t) =  s^{'''}_{\omega}(-t) =A_{\omega}|H_{\omega}|^2 e^{i \omega t } &amp;lt;/math&amp;gt; &lt;br /&gt;
: Jest to sygnał wyjściowy. &lt;br /&gt;
*Zauważmy, że względem sygnału wejściowego ma on '''amplitudę''' zmienioną &amp;lt;math&amp;gt;|H_{\omega}|^2&amp;lt;/math&amp;gt; razy i '''nie zmienioną fazę'''. &lt;br /&gt;
&lt;br /&gt;
Powyższe rozważania są prawdziwe dla dowolnego sygnału, gdyż z poprzednich zajęć wiemy, że działanie filtra (systemu LTI) można analizować niezależnie dla każdej składowej fourierowskiej.&lt;br /&gt;
=== Przykład ===&lt;br /&gt;
Procedura powyższa zaimplementowana jest w funkcji: &amp;lt;tt&amp;gt;scipy.signal.filtfilt&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Jej działanie i porównanie z efektami funkcji &amp;lt;tt&amp;gt;lfilter&amp;lt;/tt&amp;gt; przedstawia poniższy przykład:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
from scipy.signal import filtfilt, butter, freqz, lfilter&lt;br /&gt;
import numpy as np&lt;br /&gt;
import pylab as py&lt;br /&gt;
&lt;br /&gt;
# częstość próbkowania&lt;br /&gt;
Fs = 100.0&lt;br /&gt;
# projekt dolnoprzepustowego filtra Butterwortha 5 rzędu&lt;br /&gt;
# o częstości odcięcia 10 Hz  &lt;br /&gt;
[b,a] = butter(5,10.0/(Fs/2.0))&lt;br /&gt;
&lt;br /&gt;
# obliczamy funkcję przenoszenia&lt;br /&gt;
w,h = freqz(b,a,500)&lt;br /&gt;
transmitancja = np.abs(h)&lt;br /&gt;
&lt;br /&gt;
#opóźnienie grupowe&lt;br /&gt;
grupowe = -np.diff(np.unwrap(np.angle(h)))/np.diff(w)  &lt;br /&gt;
&lt;br /&gt;
# przeliczamy skalę częstości na Hz &lt;br /&gt;
f = w/(np.pi)*Fs/2.0&lt;br /&gt;
&lt;br /&gt;
# generujemy sygnał&lt;br /&gt;
t = np.arange(0,1,1/Fs)&lt;br /&gt;
s = np.sin(2*np.pi*5*t)*np.hanning(len(t))&lt;br /&gt;
&lt;br /&gt;
# Filtrowanie z zerowym opoznieniem fazowym&lt;br /&gt;
y = filtfilt(b,a,s)&lt;br /&gt;
&lt;br /&gt;
# Filtrowanie standardowe&lt;br /&gt;
y1 = lfilter(b,a,s)&lt;br /&gt;
&lt;br /&gt;
# WYKRESY&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(f,20*np.log10(transmitancja)) # przeliczenie modułu transmitancji na dB&lt;br /&gt;
py.title('transmitancja')&lt;br /&gt;
py.xlabel('[Hz]')&lt;br /&gt;
py.ylabel('[dB]')&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
py.plot(f[:-1], grupowe )&lt;br /&gt;
py.title('opoznienie grupowe')&lt;br /&gt;
py.xlabel('[Hz]')&lt;br /&gt;
py.ylabel('punkty')&lt;br /&gt;
&lt;br /&gt;
py.subplot(1,2,2)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.plot(t,y,'g.')&lt;br /&gt;
py.plot(t,y1,'r')&lt;br /&gt;
py.legend(('s','filtfilt','lfilter'))&lt;br /&gt;
py.xlabel('[s]')&lt;br /&gt;
py.title('sygnaly')&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Projektowanie filtrów w programie Svarog==&lt;br /&gt;
&lt;br /&gt;
W celu zaprojektowania filtru w Svarogu należy sprecyzować następujące parametry:&lt;br /&gt;
&lt;br /&gt;
* '''Typ filtru''' - dolnoprzepustowy, górnoprzepustowy, pasmowoprzepustowy, pasmowozaporowy.&lt;br /&gt;
* '''Rodzaj filtru''' - Butterwortha, Czebyszewa I i II, eliptyczny.&lt;br /&gt;
* '''Częstotliwość graniczna pasma przepustowego 1''' - górna częstotliwość pasma przenoszenia oddzielająca pasmo przenoszenia od obszaru przejściowego. &lt;br /&gt;
* '''Częstotliwość graniczna pasma przepustowego 2''' - w przypadku filtru pasmowoprzepustowego lub pasmowozaporowego istnieją dwa obszary przejściowego; w związku z tym częstotliwość graniczna 1 oddziela pasmo przenoszenia od pierwszego obszaru przejściowego (ma niższą wartość), a częstotliwość graniczna 2 separuje pasmo przenoszenia od drugiego obszaru przejściowego.&lt;br /&gt;
* '''Częstotliwość graniczna pasma zaporowego 1''' - dolna częstotliwość pasma zaporowego oddzielająca pasmo zaporowe od obszaru przejściowego. &lt;br /&gt;
* '''Częstotliwość graniczna pasma zaporowego 2''' -  w przypadku filtru pasmowoprzepustowego lub pasmowozaporowego częstotliwość graniczna 1 oddziela pasmo zaporowe od pierwszego obszaru przejściowego (ma niższą wartość), a częstotliwość graniczna 2 separuje pasmo zaporowe od drugiego obszaru przejściowego.&lt;br /&gt;
* '''Zafalowania w paśmie przenoszenia''' - maksymalna wartość tłumienia w paśmie przenoszenia.&lt;br /&gt;
* '''Tłumienie w paśmie zaporowym''' - minimalna wartość tłumienia w paśmie zaporowym.&lt;br /&gt;
&lt;br /&gt;
===Przykład===&lt;br /&gt;
Rysunek poniżej przedstawia charakterystykę amplitudową górnoprzepustowego filtru Czebyszewa I. Filtr został zaprojektowany przy użyciu następujących parametrów: &lt;br /&gt;
&lt;br /&gt;
* Filter type = high-pass&lt;br /&gt;
* Filter family = Chebyshev I&lt;br /&gt;
* Passband edge frequency 1 = 20 Hz&lt;br /&gt;
* Stopband edge frequency 1 = 16 Hz&lt;br /&gt;
* Passband ripple = 3 dB&lt;br /&gt;
* Stopband attenuation = 40 dB&lt;br /&gt;
&lt;br /&gt;
Rząd filtru zostaje dostosowany do wymagań projektowych.&lt;br /&gt;
&lt;br /&gt;
[[Plik:Svarog_fillter_bands.png|center|800px|thumb|&amp;lt;figure id=&amp;quot;uid3&amp;quot;/&amp;gt;Charakterystyka amplitudowa górnoprzepustowego filtru Czebyszewa I.]]&lt;br /&gt;
&lt;br /&gt;
==Zadania==&lt;br /&gt;
&lt;br /&gt;
Cel: zaobserwowanie konieczności kompromisu pomiędzy ostrym cięciem w dziedzinie częstości a &amp;quot;dobrymi&amp;quot; parametrami w dziedzinie czasu - funkcja odpowiedzi impulsowej i schodkowej.&lt;br /&gt;
&lt;br /&gt;
===Zadania===&lt;br /&gt;
&lt;br /&gt;
* Skonstruować filtry dolnoprzepustowe rzędu &amp;lt;math&amp;gt;n=5&amp;lt;/math&amp;gt;, o częstości odcięcia 30 Hz przy częstości próbkowania sygnału 128 Hz, ''rp'' = 0,5 dB, ''rs'' = 20 dB, przy pomocy wszystkich podanych powyżej funkcji i porównać ich własności.&lt;br /&gt;
* Dobrać rząd i zaprojektować, a następnie zbadać własności otrzymanego filtru Butterwortha spełniającego poniższe kryteria:&lt;br /&gt;
**pasmo przenoszenia 1000-2000 Hz, pasmo tłumienia zaczyna się 500 Hz od każdego z brzegów pasma przenoszenia, &lt;br /&gt;
**próbkowanie 10 kHz,&lt;br /&gt;
**najwyżej 1 dB tętnienia w paśmie przenoszenia, &lt;br /&gt;
**co najmniej 60 dB tłumienia w paśmie tłumienia.&lt;br /&gt;
*Zaprojektować filtr do wyławiania wrzecion snu z sygnału. Wrzeciona snu to struktury w sygnale EEG rejestrowanym w czasie snu zawierające się w paśmie 11-15 Hz. [http://www.fuw.edu.pl/~jarekz/SYGNALY/TF/c4spin.txt]. Filtr zaprojektuj w programie Svarog.&lt;br /&gt;
&lt;br /&gt;
==Przepróbkowywanie==&lt;br /&gt;
&lt;br /&gt;
===Do góry: Zwiększamy częstość prókowania całkowitą ilość razy &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. ===&lt;br /&gt;
&lt;br /&gt;
Najpowszechniej stosowana metoda polega na dodaniu &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; zer pomiędzy istniejące próbki sygnału tak aby osiągnął on &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;-krotnie większą długość. Następnie taki rozciągnięty sygnał filtrujemy filtrem dolnoprzepustowym o częstości odcięcia nie większej niż częstość Nyquista oryginalnego sygnału &amp;amp;mdash; rozciąganie sygnału nie dokłada do niego nowej informacji więc i tak nic nie tracimy.&lt;br /&gt;
&lt;br /&gt;
===Przykład przepróbkowania do góry:===&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from scipy.signal import filtfilt, butter&lt;br /&gt;
import numpy as np&lt;br /&gt;
import pylab as py&lt;br /&gt;
&lt;br /&gt;
t = np.arange(0,0.05,0.001) # czas&lt;br /&gt;
x = np.sin(2*np.pi*30*t) + np.sin(2*np.pi*60*t) # sygnał&lt;br /&gt;
&lt;br /&gt;
py.subplot(3,1,1)&lt;br /&gt;
py.plot(x,'.')&lt;br /&gt;
py.subplot(3,1,2)&lt;br /&gt;
X = np.zeros(4*len(x))&lt;br /&gt;
X[::4] = x&lt;br /&gt;
py.plot(X,'.')&lt;br /&gt;
[b,a] = butter(8,1.0/4)&lt;br /&gt;
y = filtfilt(b,a,X);&lt;br /&gt;
py.subplot(3,1,3)&lt;br /&gt;
py.plot(y,'.')&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Do dołu: Zmniejszamy częstość próbkowania całkowitą ilość razy.===&lt;br /&gt;
&lt;br /&gt;
Musimy pamiętać o tym, żeby wyfiltrować to, co było w oryginalnym sygnale powyżej docelowego Nyquista, żeby uniknąć aliasingu w wynikowym sygnale.&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from scipy.signal import filtfilt, butter&lt;br /&gt;
from numpy import pi, arange, sin&lt;br /&gt;
from pylab import plot, subplot, show, title&lt;br /&gt;
&lt;br /&gt;
Fs1 = 128.0 # pierwotna częstość próbkowania [Hz]&lt;br /&gt;
FN1 = Fs1/2 # pierwotna częstość Nyquista&lt;br /&gt;
&lt;br /&gt;
t = arange(0,1,1.0/Fs1) # czas probkowany 1/Fs1&lt;br /&gt;
f1 = 6 # Hz&lt;br /&gt;
f2 = 60&lt;br /&gt;
fi = pi/2&lt;br /&gt;
s = sin(2*pi*t*f1+fi) + sin(2*pi*t*f2+fi)&lt;br /&gt;
subplot(4,1,1)&lt;br /&gt;
plot(t,s,'.-')&lt;br /&gt;
title(u'sygnał pierwotny')&lt;br /&gt;
# obnizamy czestosc probkowania k razy&lt;br /&gt;
k = 2&lt;br /&gt;
Fs2 = Fs1/k # nowa czestosc probkowania jest k razy niższa&lt;br /&gt;
FN2 = Fs2/2 # nowa częstość Nyquista&lt;br /&gt;
[b,a] = butter(8,FN2/FN1) # przefiltrujemy filtrem dolnoprzepustowym&lt;br /&gt;
                          # tak aby nic nie zostało powyzej&lt;br /&gt;
                          # docelowej częstości Nyquista &lt;br /&gt;
ss = filtfilt(b,a,s);&lt;br /&gt;
t2 = arange(0,1,1.0/Fs2) &lt;br /&gt;
subplot(4,1,2)&lt;br /&gt;
plot(t,ss,'.-')&lt;br /&gt;
title(u'sygnał przefiltrowany dolnoprzepustowy')&lt;br /&gt;
&lt;br /&gt;
subplot(4,1,3)&lt;br /&gt;
ss2 = ss[::k]&lt;br /&gt;
plot(t2,ss2,'.-')&lt;br /&gt;
title(u'sygnał przepróbkowany prawidłowo')&lt;br /&gt;
&lt;br /&gt;
subplot(4,1,4)&lt;br /&gt;
ss3 = s[::k]&lt;br /&gt;
plot(t2,ss3,'.-')&lt;br /&gt;
title(u'sygnał przepróbkowany nieprawidłowo, bez filtrowania dolnoprzepustowego')&lt;br /&gt;
show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zmiana częstości o wymierną ilość razy:===&lt;br /&gt;
&lt;br /&gt;
Zmieniamy częstość próbkowania o wymierną &amp;lt;math&amp;gt;\frac{P}{Q}&amp;lt;/math&amp;gt; ilość razy &amp;amp;mdash; uzyskujemy składając powyższe kroki tzn. najpierw zwiększamy częstość &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;-krotnie, a następnie zmniejszamy &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;-krotnie.&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_7&amp;diff=4254</id>
		<title>Ćwiczenia 7</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_7&amp;diff=4254"/>
		<updated>2015-10-05T19:49:18Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Funkcje do projektowania filtrów IIR dostępne w module scipy.signal */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Filtry IIR==&lt;br /&gt;
&lt;br /&gt;
Filtry o nieskończonej odpowiedzi impulsowej (''infinite impulse response'', IIR) mają zazwyczaj dużo niższe rzędy niż filtry o skończonej odpowiedzi impulsowej (''finite impulse response'', FIR) z analogicznym poziomem tłumienia i szerokością pasma przejściowego.&lt;br /&gt;
&lt;br /&gt;
W module &amp;lt;tt&amp;gt;scipy.signal&amp;lt;/tt&amp;gt; mamy zaimplementowane kilka funkcji do projektowania &amp;amp;bdquo;optymalnych&amp;amp;rdquo; pod różnymi względami filtrów w klasycznych konfiguracjach:&lt;br /&gt;
dolno- albo górnoprzepustowe i pasmowo-przepustowe albo pasmowo-zaporowe.&lt;br /&gt;
&lt;br /&gt;
==Funkcje do projektowania filtrów IIR dostępne w module &amp;lt;tt&amp;gt;scipy.signal&amp;lt;/tt&amp;gt;==&lt;br /&gt;
W module &amp;lt;tt&amp;gt;scipy.signal&amp;lt;/tt&amp;gt; dostępne są funkcje do projektowania czterech typów filtrów: Butterwortha, Czebyszewa typu I i II, oraz eliptyczny.&lt;br /&gt;
Do opisu wymagań projektowych funkcje te wykorzystują następujące pojęcia:&lt;br /&gt;
* &amp;lt;tt&amp;gt;wp&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;ws&amp;lt;/tt&amp;gt; &amp;amp;mdash; krawędzie pasma przenoszenia i tłumienia. Częstości są znormalizowane do zakresu od 0 do 1 (1 odpowiada częstości Nyquista) przykładowo:&lt;br /&gt;
** dolno-przepustowy:  &amp;lt;tt&amp;gt;wp = 0.2&amp;lt;/tt&amp;gt;,          &amp;lt;tt&amp;gt;ws = 0.3&amp;lt;/tt&amp;gt;&lt;br /&gt;
** górno-przepustowy:  &amp;lt;tt&amp;gt;wp = 0.3&amp;lt;/tt&amp;gt;,          &amp;lt;tt&amp;gt;ws = 0.2&amp;lt;/tt&amp;gt;&lt;br /&gt;
** pasmowo-przepustowy:  &amp;lt;tt&amp;gt;wp = [0.2, 0.5]&amp;lt;/tt&amp;gt;,   &amp;lt;tt&amp;gt;ws = [0.1, 0.6]&amp;lt;/tt&amp;gt;&lt;br /&gt;
** pasmowo-zaporowy:  &amp;lt;tt&amp;gt;wp = [0.1, 0.6]&amp;lt;/tt&amp;gt;,   &amp;lt;tt&amp;gt;ws = [0.2, 0.5]&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;gpass&amp;lt;/tt&amp;gt; &amp;amp;mdash; maksymalna dopuszczalna strata w pasmie przenoszenia (w funkcjach projektujących filtry jest to &amp;lt;tt&amp;gt;rp&amp;lt;/tt&amp;gt;) (dB).&lt;br /&gt;
* &amp;lt;tt&amp;gt;gstop&amp;lt;/tt&amp;gt; &amp;amp;mdash; minimalne wymagane tłumienie w pasmie tłumienia (w funkcjach projektujących filtry jest to &amp;lt;tt&amp;gt;rs&amp;lt;/tt&amp;gt;) (dB).&lt;br /&gt;
* &amp;lt;tt&amp;gt;btype&amp;lt;/tt&amp;gt; &amp;amp;mdash; typ filtra (&amp;lt;tt&amp;gt;'lowpass'&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;'highpass'&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;'bandpass'&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;'bandstop'&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Funkcje do projektowania filtrów są zaimplementowane parami: jedna pomaga dobierać rząd filtru do wymagań projektowych, a druga oblicza współczynniki filtru. &lt;br /&gt;
&lt;br /&gt;
'''Filtr Butterwortha'''&lt;br /&gt;
daje gładką (bez tętnień) funkcję przenoszenia w całym zakresie częstości&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
[n,Wn]=buttord(wp, ws, gpass, gstop, analog=0)&lt;br /&gt;
[b,a]=butter(n,Wn)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; &amp;amp;mdash; rząd filtra, &amp;lt;tt&amp;gt;Wn&amp;lt;/tt&amp;gt; &amp;amp;mdash; krawędzie pasm&lt;br /&gt;
&lt;br /&gt;
'''Filtr Czebyszewa I rodzaju''' &amp;amp;mdash; gładka funkcja przenoszenia w paśmie tłumienia, minimalizowane są tętnienia  w paśmie przenoszenia&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
[n,Wn]=cheb1ord(wp, ws, gpass, gstop, analog=0);&lt;br /&gt;
[b,a]=cheby1(n, rp, Wn, btype='low', analog=0, output='ba')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Filtr Czebyszewa II''' rodzaju &amp;amp;mdash; gładka funkcja przenoszenia w paśmie przenoszenia, minimalizowane tętnienia w paśmie tłumienia&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
[n,Wn]=cheb2ord(wp, ws, gpass, gstop, analog=0);&lt;br /&gt;
[b,a]=cheby2(n, rs, Wn, btype='low', analog=0, output='ba')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Filtr eliptyczny''' daje najostrzejsze przejście pomiędzy pasmem tłumienia i przenoszenia przy tym samym rzędzie w porównaniu z wyżej wymienionymi filtrami, tętnienia są obecne zarówno w paśmie przenoszenia jak i w paśmie tłumienia&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
[n,Wn]=ellipord(Wp, Ws, Rp,Rs);&lt;br /&gt;
[b,a]=ellip(n, rp, rs, Wn, btype='low', analog=0, output='ba')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Filtrowanie z zerowym przesunięciem fazowym==&lt;br /&gt;
&lt;br /&gt;
Filtrowanie sygnałów off-line można zrealizować tak, aby sygnał wyjściowy nie miał przesunięcia fazowego. Metodę tę zaprezentujemy na poniższym przykładzie. Rozważymy co dzieje się z pojedynczą składową fourierowską sygnału o częstości &amp;lt;math&amp;gt;\omega&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Niech ta składowa nazywa się &lt;br /&gt;
:&amp;lt;math&amp;gt;s_{\omega} (t) = A_{\omega} e^{i \omega t} &amp;lt;/math&amp;gt;, &lt;br /&gt;
:natomiast transmitancja filtru dla częstości &lt;br /&gt;
:&amp;lt;math&amp;gt;H(\omega) = |H_{\omega}| e^{i \phi_{\omega}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Podając tę składową na wejście filtru, na jego wyjściu otrzymujemy &amp;lt;math&amp;gt;s^'_{\omega}(t)&amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt;s^'_{\omega}(t) = A_{\omega}|H_{\omega}| e^{i \omega t}e^{i \phi_{\omega}} &amp;lt;/math&amp;gt;&lt;br /&gt;
* korzystając z definicji przesunięcia fazowego możemy to zapisać:&lt;br /&gt;
:&amp;lt;math&amp;gt;s^'_{\omega}(t) = A_{\omega}|H_{\omega}| e^{i \omega( t- \tau_{\omega})} &amp;lt;/math&amp;gt;&lt;br /&gt;
* w sygnale tym odwracamy sekwencję czasową (kierunek czasu):&lt;br /&gt;
:&amp;lt;math&amp;gt;s^{''}_{\omega}(t) =s^{'}_{\omega}(-t) = A_{\omega}|H_{\omega}| e^{-i \omega( t- \tau_{\omega})} &amp;lt;/math&amp;gt;&lt;br /&gt;
* otrzymany sygnał podajemy na wejście filtru, wówczas na wyjściu pojawi się następujący sygnał:&lt;br /&gt;
:&amp;lt;math&amp;gt;s^{'''}_{\omega}(t) = A_{\omega}|H_{\omega}||H_{\omega}| e^{-i \omega( t- \tau_{\omega})}e^{i \phi_{\omega}} &amp;lt;/math&amp;gt;&lt;br /&gt;
* ponownie korzystając z definicji przesunięcia fazowego możemy napisać:&lt;br /&gt;
:&amp;lt;math&amp;gt;s^{'''}_{\omega}(t) = A_{\omega}|H_{\omega}|^2 e^{-i \omega t + \omega\tau_{\omega}- \omega\tau_{\omega}}= A_{\omega}|H_{\omega}|^2 e^{-i \omega t } &amp;lt;/math&amp;gt; &lt;br /&gt;
* w tym sygnale ponownie odwracamy sekwencję czasową i otrzymujemy:&lt;br /&gt;
:&amp;lt;math&amp;gt;y(t) =  s^{'''}_{\omega}(-t) =A_{\omega}|H_{\omega}|^2 e^{i \omega t } &amp;lt;/math&amp;gt; &lt;br /&gt;
: Jest to sygnał wyjściowy. &lt;br /&gt;
*Zauważmy, że względem sygnału wejściowego ma on '''amplitudę''' zmienioną &amp;lt;math&amp;gt;|H_{\omega}|^2&amp;lt;/math&amp;gt; razy i '''nie zmienioną fazę'''. &lt;br /&gt;
&lt;br /&gt;
Powyższe rozważania są prawdziwe dla dowolnego sygnału, gdyż z poprzednich zajęć wiemy, że działanie filtra (systemu LTI) można analizować niezależnie dla każdej składowej fourierowskiej.&lt;br /&gt;
=== Przykład ===&lt;br /&gt;
Procedura powyższa zaimplementowana jest w funkcji: &amp;lt;tt&amp;gt;scipy.signal.filtfilt&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Jej działanie i porównanie z efektami funkcji &amp;lt;tt&amp;gt;lfilter&amp;lt;/tt&amp;gt; przedstawia poniższy przykład:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
from scipy.signal import filtfilt, butter, freqz, lfilter&lt;br /&gt;
import numpy as np&lt;br /&gt;
import pylab as py&lt;br /&gt;
&lt;br /&gt;
# częstość próbkowania&lt;br /&gt;
Fs = 100.0&lt;br /&gt;
# projekt dolnoprzepustowego filtra Butterwortha 5 rzędu&lt;br /&gt;
# o częstości odcięcia 10 Hz  &lt;br /&gt;
[b,a] = butter(5,10.0/(Fs/2.0))&lt;br /&gt;
&lt;br /&gt;
# obliczamy funkcję przenoszenia&lt;br /&gt;
w,h = freqz(b,a,500)&lt;br /&gt;
transmitancja = np.abs(h)&lt;br /&gt;
&lt;br /&gt;
#opóźnienie grupowe&lt;br /&gt;
grupowe = -np.diff(np.unwrap(np.angle(h)))/np.diff(w)  &lt;br /&gt;
&lt;br /&gt;
# przeliczamy skalę częstości na Hz &lt;br /&gt;
f = w/(np.pi)*Fs/2.0&lt;br /&gt;
&lt;br /&gt;
# generujemy sygnał&lt;br /&gt;
t = np.arange(0,1,1/Fs)&lt;br /&gt;
s = np.sin(2*np.pi*5*t)*np.hanning(len(t))&lt;br /&gt;
&lt;br /&gt;
# Filtrowanie z zerowym opoznieniem fazowym&lt;br /&gt;
y = filtfilt(b,a,s)&lt;br /&gt;
&lt;br /&gt;
# Filtrowanie standardowe&lt;br /&gt;
y1 = lfilter(b,a,s)&lt;br /&gt;
&lt;br /&gt;
# WYKRESY&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(f,20*np.log10(transmitancja)) # przeliczenie modułu transmitancji na dB&lt;br /&gt;
py.title('transmitancja')&lt;br /&gt;
py.xlabel('[Hz]')&lt;br /&gt;
py.ylabel('[dB]')&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
py.plot(f[:-1], grupowe )&lt;br /&gt;
py.title('opoznienie grupowe')&lt;br /&gt;
py.xlabel('[Hz]')&lt;br /&gt;
py.ylabel('punkty')&lt;br /&gt;
&lt;br /&gt;
py.subplot(1,2,2)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.plot(t,y,'g.')&lt;br /&gt;
py.plot(t,y1,'r')&lt;br /&gt;
py.legend(('s','filtfilt','lfilter'))&lt;br /&gt;
py.xlabel('[s]')&lt;br /&gt;
py.title('sygnaly')&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Projektowanie filtrów w programie Svarog==&lt;br /&gt;
&lt;br /&gt;
W celu zaprojektowania filtru w Svarogu należy sprecyzować następujące parametry:&lt;br /&gt;
&lt;br /&gt;
* '''Typ filtru''' - dolnoprzepustowy, górnoprzepustowy, pasmowoprzepustowy, pasmowozaporowy.&lt;br /&gt;
* '''Rodzaj filtru''' - Butterwortha, Czebyszewa I i II, eliptyczny.&lt;br /&gt;
* '''Częstotliwość graniczna pasma przepustowego 1''' - górna częstotliwość pasma przenoszenia oddzielająca pasmo przenoszenia od obszaru przejściowego. &lt;br /&gt;
* '''Częstotliwość graniczna pasma przepustowego 2''' - w przypadku filtru pasmowoprzepustowego lub pasmowozaporowego istnieją dwa obszary przejściowego; w związku z tym częstotliwość graniczna 1 oddziela pasmo przenoszenia od pierwszego obszaru przejściowego (ma niższą wartość), a częstotliwość graniczna 2 separuje pasmo przenoszenia od drugiego obszaru przejściowego.&lt;br /&gt;
* '''Częstotliwość graniczna pasma zaporowego 1''' - dolna częstotliwość pasma zaporowego oddzielająca pasmo zaporowe od obszaru przejściowego. &lt;br /&gt;
* '''Częstotliwość graniczna pasma zaporowego 2''' -  w przypadku filtru pasmowoprzepustowego lub pasmowozaporowego częstotliwość graniczna 1 oddziela pasmo zaporowe od pierwszego obszaru przejściowego (ma niższą wartość), a częstotliwość graniczna 2 separuje pasmo zaporowe od drugiego obszaru przejściowego.&lt;br /&gt;
* '''Zafalowania w paśmie przenoszenia''' - maksymalna wartość tłumienia w paśmie przenoszenia.&lt;br /&gt;
* '''Tłumienie w paśmie zaporowym''' - minimalna wartość tłumienia w paśmie zaporowym.&lt;br /&gt;
&lt;br /&gt;
===Przykład===&lt;br /&gt;
Rysunek poniżej przedstawia charakterystykę amplitudową górnoprzepustowego filtru Czebyszewa I. Filtr został zaprojektowany przy użyciu następujących parametrów: &lt;br /&gt;
&lt;br /&gt;
* Filter type = high-pass&lt;br /&gt;
* Filter family = Chebyshev I&lt;br /&gt;
* Passband edge frequency 1 = 20 Hz&lt;br /&gt;
* Stopband edge frequency 1 = 16 Hz&lt;br /&gt;
* Passband ripple = 3 dB&lt;br /&gt;
* Stopband attenuation = 40 dB&lt;br /&gt;
&lt;br /&gt;
Rząd filtru zostaje dostosowany do wymagań projektowych.&lt;br /&gt;
&lt;br /&gt;
[[Plik:Svarog_fillter_bands.png|center|800px|thumb|&amp;lt;figure id=&amp;quot;uid3&amp;quot;/&amp;gt;Charakterystyka amplitudowa górnoprzepustowego filtru Czebyszewa I.]]&lt;br /&gt;
&lt;br /&gt;
==Zadania==&lt;br /&gt;
&lt;br /&gt;
Cel: zaobserwowanie konieczności kompromisu pomiędzy ostrym cięciem w dziedzinie częstości a &amp;quot;dobrymi&amp;quot; parametrami w dziedzinie czasu - funkcja odpowiedzi impulsowej i schodkowej.&lt;br /&gt;
&lt;br /&gt;
===Zadania===&lt;br /&gt;
&lt;br /&gt;
* Skonstruować filtry dolnoprzepustowe rzędu &amp;lt;math&amp;gt;n=5&amp;lt;/math&amp;gt;, o częstości odcięcia 30 Hz przy częstości próbkowania sygnału 128 Hz, ''rp'' = 0,5 dB, ''rs'' = 20 dB, przy pomocy wszystkich podanych powyżej funkcji i porównać ich własności.&lt;br /&gt;
* Dobrać rząd i zaprojektować, a następnie zbadać własności otrzymanego filtru Butterwortha spełniającego poniższe kryteria:&lt;br /&gt;
**pasmo przenoszenia 1000-2000 Hz, pasmo tłumienia zaczyna się 500 Hz od każdego z brzegów pasma przenoszenia, &lt;br /&gt;
**próbkowanie 10 kHz,&lt;br /&gt;
**najwyżej 1 dB tętnienia w paśmie przenoszenia, &lt;br /&gt;
**co najmniej 60 dB tłumienia w paśmie tłumienia.&lt;br /&gt;
*Zaprojektować filtr do wyławiania wrzecion snu z sygnału. Wrzeciona snu to struktury w sygnale EEG rejestrowanym w czasie snu zawierające się w paśmie 11-15 Hz. [http://www.fuw.edu.pl/~jarekz/SYGNALY/TF/c4spin.txt]&lt;br /&gt;
&lt;br /&gt;
==Przepróbkowywanie==&lt;br /&gt;
&lt;br /&gt;
===Do góry: Zwiększamy częstość prókowania całkowitą ilość razy &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. ===&lt;br /&gt;
&lt;br /&gt;
Najpowszechniej stosowana metoda polega na dodaniu &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; zer pomiędzy istniejące próbki sygnału tak aby osiągnął on &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;-krotnie większą długość. Następnie taki rozciągnięty sygnał filtrujemy filtrem dolnoprzepustowym o częstości odcięcia nie większej niż częstość Nyquista oryginalnego sygnału &amp;amp;mdash; rozciąganie sygnału nie dokłada do niego nowej informacji więc i tak nic nie tracimy.&lt;br /&gt;
&lt;br /&gt;
===Przykład przepróbkowania do góry:===&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from scipy.signal import filtfilt, butter&lt;br /&gt;
import numpy as np&lt;br /&gt;
import pylab as py&lt;br /&gt;
&lt;br /&gt;
t = np.arange(0,0.05,0.001) # czas&lt;br /&gt;
x = np.sin(2*np.pi*30*t) + np.sin(2*np.pi*60*t) # sygnał&lt;br /&gt;
&lt;br /&gt;
py.subplot(3,1,1)&lt;br /&gt;
py.plot(x,'.')&lt;br /&gt;
py.subplot(3,1,2)&lt;br /&gt;
X = np.zeros(4*len(x))&lt;br /&gt;
X[::4] = x&lt;br /&gt;
py.plot(X,'.')&lt;br /&gt;
[b,a] = butter(8,1.0/4)&lt;br /&gt;
y = filtfilt(b,a,X);&lt;br /&gt;
py.subplot(3,1,3)&lt;br /&gt;
py.plot(y,'.')&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Do dołu: Zmniejszamy częstość próbkowania całkowitą ilość razy.===&lt;br /&gt;
&lt;br /&gt;
Musimy pamiętać o tym, żeby wyfiltrować to, co było w oryginalnym sygnale powyżej docelowego Nyquista, żeby uniknąć aliasingu w wynikowym sygnale.&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from scipy.signal import filtfilt, butter&lt;br /&gt;
from numpy import pi, arange, sin&lt;br /&gt;
from pylab import plot, subplot, show, title&lt;br /&gt;
&lt;br /&gt;
Fs1 = 128.0 # pierwotna częstość próbkowania [Hz]&lt;br /&gt;
FN1 = Fs1/2 # pierwotna częstość Nyquista&lt;br /&gt;
&lt;br /&gt;
t = arange(0,1,1.0/Fs1) # czas probkowany 1/Fs1&lt;br /&gt;
f1 = 6 # Hz&lt;br /&gt;
f2 = 60&lt;br /&gt;
fi = pi/2&lt;br /&gt;
s = sin(2*pi*t*f1+fi) + sin(2*pi*t*f2+fi)&lt;br /&gt;
subplot(4,1,1)&lt;br /&gt;
plot(t,s,'.-')&lt;br /&gt;
title(u'sygnał pierwotny')&lt;br /&gt;
# obnizamy czestosc probkowania k razy&lt;br /&gt;
k = 2&lt;br /&gt;
Fs2 = Fs1/k # nowa czestosc probkowania jest k razy niższa&lt;br /&gt;
FN2 = Fs2/2 # nowa częstość Nyquista&lt;br /&gt;
[b,a] = butter(8,FN2/FN1) # przefiltrujemy filtrem dolnoprzepustowym&lt;br /&gt;
                          # tak aby nic nie zostało powyzej&lt;br /&gt;
                          # docelowej częstości Nyquista &lt;br /&gt;
ss = filtfilt(b,a,s);&lt;br /&gt;
t2 = arange(0,1,1.0/Fs2) &lt;br /&gt;
subplot(4,1,2)&lt;br /&gt;
plot(t,ss,'.-')&lt;br /&gt;
title(u'sygnał przefiltrowany dolnoprzepustowy')&lt;br /&gt;
&lt;br /&gt;
subplot(4,1,3)&lt;br /&gt;
ss2 = ss[::k]&lt;br /&gt;
plot(t2,ss2,'.-')&lt;br /&gt;
title(u'sygnał przepróbkowany prawidłowo')&lt;br /&gt;
&lt;br /&gt;
subplot(4,1,4)&lt;br /&gt;
ss3 = s[::k]&lt;br /&gt;
plot(t2,ss3,'.-')&lt;br /&gt;
title(u'sygnał przepróbkowany nieprawidłowo, bez filtrowania dolnoprzepustowego')&lt;br /&gt;
show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zmiana częstości o wymierną ilość razy:===&lt;br /&gt;
&lt;br /&gt;
Zmieniamy częstość próbkowania o wymierną &amp;lt;math&amp;gt;\frac{P}{Q}&amp;lt;/math&amp;gt; ilość razy &amp;amp;mdash; uzyskujemy składając powyższe kroki tzn. najpierw zwiększamy częstość &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;-krotnie, a następnie zmniejszamy &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;-krotnie.&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=Nieparametryczne_widmo_mocy&amp;diff=4253</id>
		<title>Nieparametryczne widmo mocy</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=Nieparametryczne_widmo_mocy&amp;diff=4253"/>
		<updated>2015-10-05T19:37:23Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Porównanie rozdzielczości i wariancji w periodogramie i w estymatorze Welcha */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Widmo mocy==&lt;br /&gt;
=== Moc===&lt;br /&gt;
Moc chwilowa sygnału przez analogię do układów elektrycznych o jednostkowym oporze jest w analizie sygnałów przyjęta jako kwadraty próbek (&amp;lt;math&amp;gt;P = I^2 R = \frac{U^2}{R}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Oznaczmy sygnał &lt;br /&gt;
&amp;lt;math&amp;gt;x[n]&amp;lt;/math&amp;gt;, wówczas jego moc wyraża się wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;P[n]=x[n]^2&amp;lt;/math&amp;gt;, &lt;br /&gt;
a energia wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;E = \sum _n{x[n]^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
==== Zadanie ====&lt;br /&gt;
Przy pomocy funkcji napisanych na poprzednich zajęciach proszę wygenerować sygnał sinusoidalny o amplitudzie 1, częstości 10 Hz, trwający 0.3 sekundy i próbkowany z częstością 1000 Hz. Proszę narysować ten sygnał przy pomocy funkcji &amp;lt;tt&amp;gt;pylab.stem&amp;lt;/tt&amp;gt;, obliczyć i narysować przebieg mocy w czasie, obliczyć energię tego sygnału.&lt;br /&gt;
&lt;br /&gt;
===Widmo mocy: tw. Plancherela i tw. Parsevala ===&lt;br /&gt;
Twierdzenia te omawiane i dowodzone były na [[Szereg_Fouriera#To.C5.BCsamo.C5.9B.C4.87_Parsevala_dla_szereg.C3.B3w_Fouriera|wykładzie]]. Tutaj, tylko krótko przypomnijmy sobie: &lt;br /&gt;
====Twierdzenie Plancherela====&lt;br /&gt;
Jeśli &amp;lt;math&amp;gt;X[k]&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;Y[k]&amp;lt;/math&amp;gt; są transformatami &amp;lt;math&amp;gt;x[n]&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;y[n]&amp;lt;/math&amp;gt; odpowiednio to:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid15&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\sum _{n=0}^{N-1} x[n]y^*[n] = \frac{1}{N} \sum _{k=0}^{N-1} X[k] Y^*[k]&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
gwiazdka oznacza sorzężenie zespolone. &lt;br /&gt;
====Twierdzenie Parsevala====&lt;br /&gt;
jest specjalnym przypadkiem twierdzenia Plancherela:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid16&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\sum _{n=0}^{N-1} \left|x[n]\right|^2 = \frac{1}{N} \sum _{k=0}^{N-1} \left|X[k]\right|^2.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
Twierdzenie to upoważnia nas do utożsamiania kwadratów wartości bezwzględnej składowych transformaty Fouriera z mocą niesioną przez odpowiadające im składowe.&lt;br /&gt;
&lt;br /&gt;
=== Zadanie: funkcja do estymacji widma mocy ===&lt;br /&gt;
Proszę napisać i przetestować funkcję realizującą następujący algorytm estymacji widma mocy:&lt;br /&gt;
# Jako parametry funkcja przyjmuje sygnał &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; i częstość próbkowania tego sygnału&lt;br /&gt;
# Oblicz transformatę Fouriera sygnału przy pomocy &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Unormuj otrzymaną transformatę przez pierwiastek z ilości próbek sygnału&lt;br /&gt;
# Oblicz moc jako iloczyn unormowanej transformaty i jej sprzężenia zespolonego. W pythonie sprzężenie zespolone liczby &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; otrzymujemy korzystając z metody &amp;lt;tt&amp;gt;S.conj()&amp;lt;/tt&amp;gt;. W wyniku powyższego iloczynu dostaniemy liczby zespolone o zerowej części urojonej (proszę to sprawdzić). &lt;br /&gt;
# Do dalszych operacji wybierz tylko część rzeczywistą mocy. Część rzeczywistą liczby zespolonej M pobieramy w następujący sposób: &amp;lt;tt&amp;gt;czesc_rzeczywista_M = M.real&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Korzystając z funkcji &amp;lt;tt&amp;gt;fftfreq&amp;lt;/tt&amp;gt; obliczamy częstości, dla których policzone są współczynniki Fouriera.&lt;br /&gt;
# Przy pomocy funkcji &amp;lt;tt&amp;gt;fftshift&amp;lt;/tt&amp;gt; porządkujemy kolejność wektorów mocy i częstości, tak aby częstości były reprezentowane od -częstości Nyquista, przez 0, do +częstości Nyquista&lt;br /&gt;
# zwracamy uporządkowane wektory mocy i częstości&lt;br /&gt;
&lt;br /&gt;
Testowanie:&lt;br /&gt;
&lt;br /&gt;
# przy pomocy funkcji sin napisanej na drugich ćwiczeniach  wygeneruj sinusoidę o długości 1 s, o częstości 10Hz, próbkowaną 100 Hz.&lt;br /&gt;
# oblicz moc w czasie (trzeba podnieść wartość każdej próbki do kwadratu)&lt;br /&gt;
# oblicz moc w częstości przy pomocy funkcji estymacji widma mocy&lt;br /&gt;
# oblicz energię sygnału w czasie&lt;br /&gt;
# oblicz energię sygnału w częstości&lt;br /&gt;
# wykreśl: &lt;br /&gt;
#* sygnał&lt;br /&gt;
#* przebieg jego mocy w czasie&lt;br /&gt;
#* przebieg mocy w częstości&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import rfft,fft,fftfreq,fftshift&lt;br /&gt;
 &lt;br /&gt;
def widmo_mocy(s, Fs):&lt;br /&gt;
    S = fft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = S*S.conj()&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (fftshift(S_moc),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
(s,t) = sin(f=10,Fs=100.0)&lt;br /&gt;
moc_w_czasie = s**2&lt;br /&gt;
(moc_w_czestosci, F) = widmo_mocy(s, Fs=100.0)&lt;br /&gt;
&lt;br /&gt;
energia_w_czasie = np.sum(moc_w_czasie)&lt;br /&gt;
energia_w_czestosci = np.sum(moc_w_czestosci)&lt;br /&gt;
print 'energia w czasie: ', energia_w_czasie&lt;br /&gt;
print 'energia w czestosci: ', energia_w_czestosci&lt;br /&gt;
&lt;br /&gt;
py.subplot(3,1,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title('Sygnał')&lt;br /&gt;
py.subplot(3,1,2)&lt;br /&gt;
py.plot(t,moc_w_czasie)&lt;br /&gt;
py.title('moc w czasie')&lt;br /&gt;
py.subplot(3,1,3)&lt;br /&gt;
py.plot(F,moc_w_czestosci)&lt;br /&gt;
py.title('moc w częstości')&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===Rozdzielczość widma===&lt;br /&gt;
Proszę zbadać rozdzielczość częstotliwościową widma w zależności od długości sygnału. Używamy funkcji &amp;lt;tt&amp;gt;m_sin&amp;lt;/tt&amp;gt;. Zwrócić uwagę na to co dzieje się na końcach odcinka.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Okienkowanie a widmo mocy: periodogram===&lt;br /&gt;
Przypomnijmy wzór na dyskretną transformatę Fouriera [http://haar.zfb.fuw.edu.pl/edu/index.php/%C4%86wiczenia_2 DFT] zaimplementowaną w FFT: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;S[k] =  \sum_{n=0}^{n-1} s[n] \exp\left\{-2\pi i{nk \over N}\right\}       \qquad k = 0,\ldots,N-1.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Na podstawie twierdzenia [[Nieparametryczne_widmo_mocy#Twierdzenie_Parsevala|Parsevala]] możemy policzyć widmo mocy jako:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P[k] = \frac{1}{N}  \left|S[k]\right|^2 &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeśli do liczenia mocy chcielibyśmy posłużyć się techniką okiennkowania sygnału, to powinniśmy używać okienek znormalizowanych, czyli takich których energia jest równa 1, wtedy mnożenie przez okienko nie zaburzy estymaty energii sygnału. &lt;br /&gt;
&lt;br /&gt;
Aby policzyć widmo mocy sygnału z zastosowaniem okienek wprowadzimy następujące symbole:&lt;br /&gt;
* sygnał: &amp;lt;math&amp;gt;s[n]&amp;lt;/math&amp;gt;&lt;br /&gt;
* okienko: &amp;lt;math&amp;gt; w[n]&amp;lt;/math&amp;gt;&lt;br /&gt;
* okienko znormalizowane: &amp;lt;math&amp;gt; \hat w[n] = \frac{1}{\sqrt{\sum_{n=0}^{N-1} (w[n])^2}}w[n]&amp;lt;/math&amp;gt; &lt;br /&gt;
&amp;lt;!--(w szczególnym przypadku okienka prostokątnego normalizacja ta daje &amp;lt;math&amp;gt;1/N^2&amp;lt;/math&amp;gt; występujące we wzorze na moc)--&amp;gt;&lt;br /&gt;
* widmo mocy sygnału okienkowanego:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P[k] = \frac{1}{\sum_{n=0}^{N-1} (w[n])^2}  \left|\sum_{n=0}^{N-1} s[n]w[n] e^{i\frac{2 \pi }{N} k n}\right|^2 &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Zadanie ====&lt;br /&gt;
Proszę napisać funkcję obliczającą periodogram.&lt;br /&gt;
Funkcja jako argumenty powinna przyjmować sygnał, okno (podane jako sekwencja próbek), i częstość próbkowania. Zwracać powinna widmo mocy i skalę osi częstości. Wewnątrz funkcja powinna implementować liczenie widma z sygnału okienkowanego znormalizowanym oknem.&lt;br /&gt;
&lt;br /&gt;
Funkcję proszę przetestować obliczając dla funkcji sinus energię sygnału w dziedzinie czasu i w dziedzinie częstości. Testy proszę wykonać dla okna prostokątnego, Blackmana i Haminga.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , F_samp):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    F_samp- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 10.1, T =2, Fs = F_samp, phi = 0)&lt;br /&gt;
N = len(x) # dłogość sygnału&lt;br /&gt;
okno = np.ones(N)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N)&lt;br /&gt;
#okno = np.hamming(N)&lt;br /&gt;
&lt;br /&gt;
s = x*okno # sygnał okienkowany&lt;br /&gt;
#&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,x)&lt;br /&gt;
energia_t = np.sum(x**2)&lt;br /&gt;
print 'energia sygnału:', energia_t&lt;br /&gt;
py.title(u' sygnał')&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał')&lt;br /&gt;
py.title(u' sygnał okienkowany ')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
(S,F) = widmo_dB(s,N,F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego')&lt;br /&gt;
py.ylabel('dB')&lt;br /&gt;
&lt;br /&gt;
#periodogram&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
(P, F) = periodogram(x,okno,F_samp)&lt;br /&gt;
py.plot(F,P)&lt;br /&gt;
        &lt;br /&gt;
py.title('periodogram')&lt;br /&gt;
print 'energia periodogramu:', np.sum(P)&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Sygnały stochastyczne ==&lt;br /&gt;
Sygnał stochastyczny to taki sygnał, dla którego ciągu próbek nie da się opisać funkcją czasu. Kolejne próbki w takim sygnale to [[WnioskowanieStatystyczne/Zmienne_losowe_i_generatory_liczb_pseudolosowych#Zmienna_losowa|zmienne losowe]]. Można je opisać podając własności [[WnioskowanieStatystyczne/Zmienne_losowe_i_generatory_liczb_pseudolosowych#Rozk.C5.82ad_prawdopodobie.C5.84stwa|rozkładu]], z k†órego pochodzą. Często w opisie takich zmiennych posługujemy się [[WnioskowanieStatystyczne/Zmienne_losowe_i_generatory_liczb_pseudolosowych#Momenty|momentami rozkładów]].&lt;br /&gt;
Jak można sobie wyobrazić rozkłady, z których pochodzą próbki?&lt;br /&gt;
Można sobie wyobrazić,że obserwowany przez nas sygnał stochastyczny to jedna z możliwych realizacji procesu stochastycznego. &lt;br /&gt;
Jeśli &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; jest zbiorem &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; zdarzeń (&amp;lt;math&amp;gt;k \in K&amp;lt;/math&amp;gt;) i każde z tych zdarzeń ma przypisaną funkcję &amp;lt;math&amp;gt;x_k(t)&amp;lt;/math&amp;gt; zwaną realizacją procesu &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt;, to proces stochastyczny może być zdefiniowany jako zbiór funkcji:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid23&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\xi (t) = \left\lbrace x_1(t),x_2(t),\dots , x_N(t) \right\rbrace &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;x_k(t)&amp;lt;/math&amp;gt; są losowymi funkcjami czasu &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Procesy stochastyczne można opisywać prze wartości oczekiwane liczone po realizacjach.&lt;br /&gt;
&lt;br /&gt;
Dla przypomnienia wartość oczekiwaną liczymy tak:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid24&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
{\mu _x(t_1) = E\left[\xi (t_1) \right]= \lim _{N \rightarrow \infty }\sum _{k=1}^{N}{x_k(t_1)} p(x_k,t_1)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
średnia &amp;lt;math&amp;gt;\mu _x(t_1)&amp;lt;/math&amp;gt; procesu &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt; w chwili &amp;lt;math&amp;gt;t_1&amp;lt;/math&amp;gt; to suma wartośći zaobserwowanych w chwili we wszystkich realizacjach &amp;lt;math&amp;gt;t_1&amp;lt;/math&amp;gt; ważona prawdopodobieństwem wystąpienia tej realizacji:&lt;br /&gt;
=== Stacjonarność i ergodyczność===&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
	&amp;lt;dt&amp;gt;&lt;br /&gt;
	Stacjonarność:&lt;br /&gt;
	&amp;lt;dd&amp;gt;&lt;br /&gt;
	Jeśli dla procesu stochastycznego &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt; wszystkie momenty są niezależne od czasu to jest on stajonarny w ścisłym sensie. Jeśli tylko średnia &amp;lt;math&amp;gt;\mu _x&amp;lt;/math&amp;gt; i autokorelacja &amp;lt;math&amp;gt;R_x(\tau )&amp;lt;/math&amp;gt; nie zależą od czasu to proces jest stacjonarny w słabym sensie, co dla wielu zastosowań jest wystarczające.&lt;br /&gt;
	&amp;lt;dt&amp;gt;&lt;br /&gt;
	Ergodyczność:&lt;br /&gt;
	&amp;lt;dd&amp;gt;&lt;br /&gt;
	Proces jest ergodyczny jeśli jego średnie po czasie i po realizacjach są sobie równe. Oznacza to, że dla takiego procesu jedna realizacja jest reprezentatywna i zawiera całą informację o tym procesie.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Założenie o sygnale, że jest stacjonarny i ergodyczny pozwala zamienić sumowanie po realizacjach na sumowanie po czasie w estymatory momentów statystycznych.&lt;br /&gt;
&lt;br /&gt;
===Transformata Fouriera sygnału stochastycznego===&lt;br /&gt;
Bardzo często musimy oszacować widmo mocy sygnału zawierającego znaczny udział szumu.&lt;br /&gt;
&lt;br /&gt;
Poniższe ćwiczenie ilustruje niepewność szacowania pików w widmie otrzymanym z transformaty Fouriera dla sygnału zawierającego szum.&lt;br /&gt;
&lt;br /&gt;
* wygeneruj 20 realizacji sygnału będącego sumą sinusoidy (f = 20 Hz, T = 1 s, Fs = 100 Hz) i  szumu gaussowskiego&lt;br /&gt;
* dla każdej realizacji oblicz widmo mocy&lt;br /&gt;
* wykreśl wszystkie otrzymane widma na wspólnym wykresie&lt;br /&gt;
&lt;br /&gt;
Proszę obejrzeć otrzymane widma.&lt;br /&gt;
* Zaobserwuj jakiego rzędu jest niepewność wyniku.&lt;br /&gt;
* Czy podobny problem występuje dla sygnału bez szumu?&lt;br /&gt;
* Skonstruuj funkcję rysującą średnie widmo wraz z [[WnioskowanieStatystyczne/_Przedzia%C5%82y_ufno%C5%9Bci|przedziałem ufności]].&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import scipy.stats as st&lt;br /&gt;
&lt;br /&gt;
from numpy.fft import rfft,fft,fftfreq,fftshift&lt;br /&gt;
 &lt;br /&gt;
def widmo_mocy(s, Fs):&lt;br /&gt;
    '''funkcja oblicza widmo mocy sygnału i oś częstości&lt;br /&gt;
    s - sygnał&lt;br /&gt;
    Fs - częstość próbkowania&lt;br /&gt;
    '''&lt;br /&gt;
    S = fft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = S*S.conj()&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (fftshift(S_moc),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def widmo_mocy_rzeczywistego(s,FS):&lt;br /&gt;
    '''funkcja oblicza widmo mocy sygnału rzeczywistego i oś częstości&lt;br /&gt;
    s - sygnał&lt;br /&gt;
    Fs - częstość próbkowania&lt;br /&gt;
&lt;br /&gt;
    zwraca dodatnią część widma&lt;br /&gt;
    '''&lt;br /&gt;
    S = rfft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = np.abs(S)**2&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (S_moc,F)&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def szum(mu =0 , sigma = 1, T = 1, Fs = 128):&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.random.randn(len(t) )*sigma + mu&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def dwadziescia_realizacji(FS):&lt;br /&gt;
    '''&lt;br /&gt;
    *  wygeneruj 20 realizacji sygnału będącego sumą sinusoidy (f=20Hz, T=1s, Fs =100Hz) i szumu gassowskiego&lt;br /&gt;
    * dla każdej realizacji oblicz widmo mocy&lt;br /&gt;
    * wykreśl wszystkie otrzymane widma na wspólnym wykresie &lt;br /&gt;
    '''&lt;br /&gt;
    for i in range(20):&lt;br /&gt;
        (s,t) = sin(f=10,Fs=FS)&lt;br /&gt;
        (sz,t) = szum(Fs =FS)&lt;br /&gt;
        syg = s + sz&lt;br /&gt;
        (moc_w_czestosci, F) = widmo_mocy(syg, Fs=FS)&lt;br /&gt;
        py.plot(F,moc_w_czestosci)&lt;br /&gt;
    py.show()&lt;br /&gt;
    &lt;br /&gt;
def srednie_widmo(FS):&lt;br /&gt;
    '''&lt;br /&gt;
    #  Skonstruuj funkcję rysującą średnie widmo wraz z 95% przedziałem ufności. &lt;br /&gt;
    '''&lt;br /&gt;
    zbior_widm = np.zeros((20,FS))&lt;br /&gt;
    for i in range(20):&lt;br /&gt;
        (s,t) = sin(f=10,Fs=FS)&lt;br /&gt;
        (sz,t) = szum(Fs =FS)&lt;br /&gt;
        syg = s + sz&lt;br /&gt;
        (moc_w_czestosci, F) = widmo_mocy(syg, Fs=FS)&lt;br /&gt;
        zbior_widm[i][:] = moc_w_czestosci&lt;br /&gt;
    srednie_w = np.mean(zbior_widm,axis =0)&lt;br /&gt;
    przedzial_d = np.zeros(len(F))&lt;br /&gt;
    przedzial_g = np.zeros(len(F))&lt;br /&gt;
    for f in F:&lt;br /&gt;
        przedzial_d[f] = st.scoreatpercentile(zbior_widm[:,f], 2.5)&lt;br /&gt;
        przedzial_g[f] = st.scoreatpercentile(zbior_widm[:,f], 97.5)&lt;br /&gt;
    py.plot(F,srednie_w,'r')&lt;br /&gt;
    py.plot(F,przedzial_d,'b')&lt;br /&gt;
    py.plot(F,przedzial_g,'b')&lt;br /&gt;
    py.show()&lt;br /&gt;
&lt;br /&gt;
FS =100.0    &lt;br /&gt;
#dwadziescia_realizacji(FS)&lt;br /&gt;
srednie_widmo(FS)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Oszacowanie błędu transformaty Fouriera dla białego szumu ===&lt;br /&gt;
Dla sygnału stochastycznego &amp;lt;math&amp;gt;x(t)&amp;lt;/math&amp;gt;, którego kolejne próbki pochodzą z niezależnych rozkładów normalnych (biały szum), jego transformata Fouriera &amp;lt;math&amp;gt;X(f)&amp;lt;/math&amp;gt; jest liczbą zespoloną, której część rzeczywista &amp;lt;math&amp;gt;X_R(f)&amp;lt;/math&amp;gt; i urojona &amp;lt;math&amp;gt;X_I(f)&amp;lt;/math&amp;gt; mogą być uznane za nieskorelowane zmienne losowe o średniej zero i równych wariancjach. Ponieważ transformata Fouriera jest operacją liniową więc składowe  &amp;lt;math&amp;gt;X_R(f)&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;X_I(f)&amp;lt;/math&amp;gt; mają rozkłady normalne. Zatem wielkość:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P(f) = |X(f)|^2 = X_R^2(f) + X_I^2(f)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
jest sumą kwadratów dwóch niezależnych zmiennych normalnych. Wielkość ta podlega zatem rozkładowi &amp;lt;math&amp;gt;\chi^2&amp;lt;/math&amp;gt; o dwóch stopniach swobody.&lt;br /&gt;
Możemy oszacować względny błąd &amp;lt;math&amp;gt;P(f_1) &amp;lt;/math&amp;gt; dla danej częstości &amp;lt;math&amp;gt;f_1&amp;lt;/math&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\epsilon_r= \sigma_{P_{f_1}}/\mu_{P_{f_1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dla rozkładu &amp;lt;math&amp;gt;\chi_2^2&amp;lt;/math&amp;gt;:  &amp;lt;math&amp;gt;\sigma^2 = 2n&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;\mu = n&amp;lt;/math&amp;gt;, gdzie &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; jest ilością stopni swobody. W naszym przypadku &amp;lt;math&amp;gt;n =2&amp;lt;/math&amp;gt; więc mamy &amp;lt;math&amp;gt;\epsilon_f = 1&amp;lt;/math&amp;gt;, co oznacza, że dla pojedynczego binu częstości w widmie &amp;lt;math&amp;gt;P(f)&amp;lt;/math&amp;gt; względny błąd wynosi 100%. &lt;br /&gt;
&lt;br /&gt;
Aby zmniejszyć ten błąd trzeba zwiększyć ilość stopni swobody. Są generalnie stosowane dwie techniki. Pierwsza to uśrednianie sąsiednich binów częstości. Otrzymujemy wówczas wygładzony estymator mocy &amp;lt;math&amp;gt;\hat{P}_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\hat{P}_k = \frac{1}{l}[P_k + P_{k+1} + \dots + P_{k+l-1}]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zakładając, że biny częstości  &amp;lt;math&amp;gt;P_i&amp;lt;/math&amp;gt; są niezależne estymator &amp;lt;math&amp;gt;P_k&amp;lt;/math&amp;gt; ma rozkład &amp;lt;math&amp;gt;\chi^2&amp;lt;/math&amp;gt; o ilości stopni swobody równej &amp;lt;math&amp;gt;n= 2l&amp;lt;/math&amp;gt;. Względny błąd takiego estymatora to: &amp;lt;math&amp;gt;\epsilon_r= \sqrt{\frac{1}{l}}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Innym sposobem poprawy estymatora mocy jest podzielenie sygnału na fragmenty, obliczenie periodogramu dla każdego fragmentu, a następnie zsumowanie otrzymanych wartości:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\hat{P}_k=[P_{k,1}+P_{k,2}+\dots+P_{k,j}+\dots+P_{k,q}]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;S_{k,j}&amp;lt;/math&amp;gt; jest estymatą składowej o częstości &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; w oparciu o &amp;lt;math&amp;gt;j-ty&amp;lt;/math&amp;gt; fragment sygnału. Ilość stopni swobody wynosi w tym przypadku &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; zatem względny błąd wynosi: &amp;lt;math&amp;gt;\epsilon_r = \sqrt{\frac{1}{q}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Zauważmy, że w obu metodach zmniejszamy wariancję estymatora kosztem rozdzielczości w częstości.&lt;br /&gt;
&lt;br /&gt;
===Metoda Welcha===&lt;br /&gt;
Proszę napisać i przetestować funkcję implementującą metodę Welcha estymacji widma mocy. Algorytm Welcha:&lt;br /&gt;
# sygnał &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; o długości ''N'' jest dzielony na segmenty, każdy o długości &amp;lt;math&amp;gt;N_s&amp;lt;/math&amp;gt;. Odcinki mogą na siebie zachodzić na &amp;lt;math&amp;gt;N_z&amp;lt;/math&amp;gt; punktów. Czyli są względem siebie przesunięte o &amp;lt;math&amp;gt;N_p = N_s-N_z&amp;lt;/math&amp;gt;.&lt;br /&gt;
# z każdego segmentu liczony jest okienkowany periodogram&lt;br /&gt;
# periodogramy są sumowane&lt;br /&gt;
# wynik dzielony jest przez efektywne wykorzystanie każdego kawałka sygnału w estymacie: &amp;lt;tt&amp;gt;K_eff = dlogosc_okna * ilosc_okien / dlugosc_sygnalu&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funkcję proszę przetestować obliczając dla funkcji sinus energię sygnału w dziedzinie czasu i w dziedzinie częstości. Testy proszę wykonać dla okna prostokątnego, Blackmana i Haminga. &lt;br /&gt;
&lt;br /&gt;
 * &amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
def pwelch(s,okienko, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okienko)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,F_samp)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Całość razem z kodem testującym:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , Fs):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    Fs- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
def pwelch(s,okienko, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okienko)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,Fs)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 3.1, T =20, Fs = F_samp, phi = 0)&lt;br /&gt;
N = len(x) # dłogość sygnału&lt;br /&gt;
&lt;br /&gt;
okno = np.ones(N)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N)&lt;br /&gt;
#okno = np.hamming(N)&lt;br /&gt;
&lt;br /&gt;
s = x*okno # sygnał okienkowany&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
(P, F) = periodogram(x,okno,F_samp)&lt;br /&gt;
py.plot(F,P) &lt;br /&gt;
py.title('periodogram'+' energia: '+ str(np.sum(P)))&lt;br /&gt;
&lt;br /&gt;
#periodogram&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
N_s = N/8&lt;br /&gt;
#okno = np.ones(N_s)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N_s)&lt;br /&gt;
okno = np.hamming(N_s)&lt;br /&gt;
&lt;br /&gt;
         &lt;br /&gt;
(P, F) = pwelch(x,okno,N_s/10,F_samp)&lt;br /&gt;
py.plot(F,P)&lt;br /&gt;
py.title('periodogram Welcha'+' energia: '+ str(np.sum(P)))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Porównanie rozdzielczości i wariancji w periodogramie i w estymatorze Welcha===&lt;br /&gt;
#  wygeneruj 100 realizacji sygnału będącego sumą sinusoidy (f = 20 Hz, T = 10 s, Fs = 100 Hz) i szumu gaussowskiego&lt;br /&gt;
# dla każdej realizacji oblicz widmo mocy za pomocą periodogramu okienkowanego oknem Blackmana&lt;br /&gt;
# wykreśl wszystkie otrzymane widma na wspólnym wykresie (subplot(2,1,1))&lt;br /&gt;
# Powtórz krok 2) dla estymatora Welcha z oknem Blackmana o długości 1/10 długości sygnału przesuwanym co 2 punkty, otrzymane widma wykreśl  na wspólnym wykresie (subplot(2,1,2))&lt;br /&gt;
&lt;br /&gt;
* Co można powiedzieć o rozdzielczości i względnym błędzie obu metod?&lt;br /&gt;
&amp;lt;tt&amp;gt;bl_wzg = np.std(S,axis = 0)/np.mean(S,axis = 0)&amp;lt;/tt&amp;gt; gdzie S jest tablicą zawierającą widma dla każdej z realizacji.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , Fs):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    Fs- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/Fs)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
def pwelch(s,okno, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okno)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,Fs)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&lt;br /&gt;
def realizacja(T,Fs):&lt;br /&gt;
    (x,t) = sin(f = 20.0, T = T, Fs = Fs, phi = 0)&lt;br /&gt;
    x += 2*np.random.randn(len(x))&lt;br /&gt;
    return x&lt;br /&gt;
&lt;br /&gt;
T=10.0&lt;br /&gt;
Fs = 100.0&lt;br /&gt;
N = T*Fs&lt;br /&gt;
Nw = N/10.0&lt;br /&gt;
okno = np.blackman(N)&lt;br /&gt;
okno_welch = np.blackman(Nw)&lt;br /&gt;
&lt;br /&gt;
N_rep = 100&lt;br /&gt;
S_perio = np.zeros((N_rep,N))&lt;br /&gt;
S_welch = np.zeros((N_rep,Nw))&lt;br /&gt;
py.figure(1)&lt;br /&gt;
for i in range(N_rep):&lt;br /&gt;
    s = realizacja(T,Fs)&lt;br /&gt;
    (P, F) = periodogram(s,okno,Fs) &lt;br /&gt;
    S_perio[i] = P&lt;br /&gt;
    py.subplot(2,1,1)&lt;br /&gt;
    py.plot(F,P) &lt;br /&gt;
    (P, F) = pwelch(s,okno_welch,Nw/10,Fs)&lt;br /&gt;
    S_welch[i] = P&lt;br /&gt;
    py.subplot(2,1,2)&lt;br /&gt;
    py.plot(F,P)&lt;br /&gt;
&lt;br /&gt;
py.figure(2)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(np.std(S_perio,axis = 0)/np.mean(S_perio,axis = 0))&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.std(S_welch,axis = 0)/np.mean(S_welch,axis = 0))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Wielookienkowa metoda Thomsona===&lt;br /&gt;
Metoda ta &lt;br /&gt;
[http://ieeexplore.ieee.org/Xplore/login.jsp?url=http%3A%2F%2Fieeexplore.ieee.org%2Fiel5%2F5%2F31317%2F01456701.pdf%3Farnumber%3D1456701&amp;amp;authDecision=-201 Spectrum estimation and harmonic analysis] &lt;br /&gt;
znana jest pod anglojęzyczną nazwą  ''multitaper''. &lt;br /&gt;
&lt;br /&gt;
Można ją opisać poniższym algorytmem:&lt;br /&gt;
* wygeneruj sekwencję ortogonalnych okienek charakteryzujących się minimalnymi wyciekami widma (stosunek energii w piku centralnym do energii w listkach bocznych jest wysoki). Sekwencja takich okien nazywana jest discrete prolate spheroidal sequences (DPSS) lub sekwencją Slepiana.&lt;br /&gt;
* oblicz widmo sygnału okienkowanego każdym z okien w sekwencji&lt;br /&gt;
* uśrednij otrzymane widma&lt;br /&gt;
&lt;br /&gt;
Kolejne dwa zadania służą zapoznaniu się z tą metodą.&lt;br /&gt;
====Własności okienek DPSS ====&lt;br /&gt;
Do generacji sekwencji okienek DPSS wykorzystamy moduł [http://brain.fuw.edu.pl/edu-wiki/images/f/f6/Gendpss.py Gendpss.py]. Proszę go zapisać w swoim katalogu roboczym. &lt;br /&gt;
Importujemy go do naszych programów tak jak każdy inny moduł np.:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import Gendpss as dpss&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Funkcja potrzebna nam z tego modułu to &amp;lt;tt&amp;gt;gendpss()&amp;lt;/tt&amp;gt;. Funkcja ta wytwarza obiekt reprezentujący konkretną sekwencję DPSS. Wywołujemy ją następująco:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
w = dpss.gendpss(N,NW,K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:gdzie: N: długość okna,&lt;br /&gt;
:        NW: iloczyn czas-szerokość pasma&lt;br /&gt;
:        K: ile okien w sekwencji&lt;br /&gt;
Po powyższym wywołaniu obiekt &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; posiada dwie interesujące nas tablice:&lt;br /&gt;
* &amp;lt;tt&amp;gt;w.lambdas&amp;lt;/tt&amp;gt; - to wartości własne okienek. Są one miarą koncentracji energii w piku głównym, jest to zatem miara jakości okienka (dobre okienka mają wartości własne bliskie 1). Zgodnie z teorią takich wartości powinno być 2*NW-1.&lt;br /&gt;
* &amp;lt;tt&amp;gt;w.dpssarray[i]&amp;lt;/tt&amp;gt; - i-te okienko.&lt;br /&gt;
&lt;br /&gt;
=====Polecenia:=====&lt;br /&gt;
Proszę:&lt;br /&gt;
* wygenerować okienka o długości 256, NW = 2. Ilość okien K raz ustalić na 3 (2*NW-1) a drugi raz na 5. Dla ilu okienek ich wartości własne są bliskie 1?&lt;br /&gt;
* narysować przebieg czasowy okienek&lt;br /&gt;
* sprawdzić czy energia okienek jest znormalizowana do 1.&lt;br /&gt;
* sprawdzić czy kolejne okienka są do siebie ortogonalne. W tym celu należy obliczyć iloczyn skalarny pomiędzy kolejnymi okienkami (np.sum(w.dpssarray[i]*w.dpssarray[j])). &lt;br /&gt;
* wywrysować widma okienek analogicznie jak [[%C4%86wiczenia_3#Badanie_w.C5.82asno.C5.9Bci_okien|w tym ćwiczeniu]]&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import gendpss as dpss&lt;br /&gt;
from numpy.fft import fft,fftshift,fftfreq&lt;br /&gt;
&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1.0/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NW = 2&lt;br /&gt;
ile_okien = 5#2*NW-1&lt;br /&gt;
N_okna = 256&lt;br /&gt;
w = dpss.gendpss(N=N_okna,NW=NW,K=ile_okien)&lt;br /&gt;
print 'Wartości własne:'&lt;br /&gt;
print w.lambdas&lt;br /&gt;
&lt;br /&gt;
print 'Wartości iloczynów skalarnych pomiędzy kolejnymi okienekami:'&lt;br /&gt;
py.figure(1)&lt;br /&gt;
for i in range(ile_okien):&lt;br /&gt;
    py.plot(w.dpssarray[i])&lt;br /&gt;
    for j in range(i+1):&lt;br /&gt;
        print np.sum(w.dpssarray[i]*w.dpssarray[j]),&lt;br /&gt;
    print&lt;br /&gt;
&lt;br /&gt;
py.figure(2)&lt;br /&gt;
NFFT = N_okna*4&lt;br /&gt;
S=np.zeros((ile_okien,NFFT))&lt;br /&gt;
for i in range(ile_okien):&lt;br /&gt;
    py.subplot(ile_okien,1,i+1)&lt;br /&gt;
    (S_db, F)= widmo_dB(w.dpssarray[i], NFFT, 1.0)&lt;br /&gt;
    S[i,:]=S_db&lt;br /&gt;
    py.plot(F,S_db)&lt;br /&gt;
    py.ylim((-200,20))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Estymacja widma mocy metodą multitaper ====&lt;br /&gt;
Proszę napisać funkcję do estymacji mocy metodą multitaper.&lt;br /&gt;
Funkcja powinna pobierać następujące argumenty: sygnał, iloczyn NW, częstość próbkowania sygnału. Funkcja powinna zwracać krotkę &amp;lt;tt&amp;gt;(S,F)&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; widmo mocy, &amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt; skala częstości.&lt;br /&gt;
Przykładowe wywołanie takiej funkcji powinno wyglądać tak:&lt;br /&gt;
&amp;lt;tt&amp;gt; (S,F) = mtm(s,  NW = 3, Fs = 128)&amp;lt;/tt&amp;gt;&lt;br /&gt;
Algorytm do zastosowania wewnątrz funkcji:&lt;br /&gt;
# Oblicz maksymalną liczbę okienek &amp;lt;tt&amp;gt; K = 2*NW-1&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Oblicz długość sygnału&lt;br /&gt;
# wygeneruj serię okienek dpss&lt;br /&gt;
# dla każdego z otrzymanych okienek oblicz widmo mocy iloczynu tego okienka i sygnału. Dla i-tego okienka będzie to: &amp;lt;tt&amp;gt;Si = np.abs(fft(s*w.dpssarray[i]))**2&amp;lt;/tt&amp;gt;&lt;br /&gt;
# uśrednij widma otrzymane dla wszystkich okienek&lt;br /&gt;
# wygeneruj oś częstości (&amp;lt;tt&amp;gt;fftfreq&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Działanie funkcji sprawdź estymując i wykreślając widmo sinusoidy np. o częstości 10 Hz, czasie trwania 1s, próbkowanej 100Hz z dodanym szumem gaussowskim o średniej 0 i wariancji 1. Sprawdź także zachowanie energii przez tą estymatę. Dla porównania na tym samym wykresie dorysuj widmo otrzymane przez [[Nieparametryczne_widmo_mocy#Okienkowanie_a_widmo_mocy:_periodogram|periodogram]] z oknem prostokątnym.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import gendpss as dpss&lt;br /&gt;
from numpy.fft import fft,fftshift,fftfreq&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def mtm(s, NW = 3, Fs = 128):&lt;br /&gt;
    '''estymacja widma w oparciu o  metodę Multiteper &lt;br /&gt;
    D. J. Thomson, “Spectrum Estimation and Harmonic Analysis,” Proceedings of the&lt;br /&gt;
    IEEE, vol. 70, no. 9, pp. 1055 – 1096, 1982.&lt;br /&gt;
    x - sygnał&lt;br /&gt;
    N -ilość punktów okna&lt;br /&gt;
    NW - iloczyn długości okna w czasie i szerokości w częstości&lt;br /&gt;
    K - ilość okien&lt;br /&gt;
&lt;br /&gt;
    funkcja zwraca estymatę mocy widmowej&lt;br /&gt;
    '''&lt;br /&gt;
    K = 2*NW-1&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    w = dpss.gendpss(N,NW,K)&lt;br /&gt;
    S=np.zeros(N)&lt;br /&gt;
    for i in range(K):&lt;br /&gt;
        Si = np.abs(fft(s*w.dpssarray[i]))**2&lt;br /&gt;
        S[:] += Si.real&lt;br /&gt;
    S = S/K&lt;br /&gt;
    F = fftfreq(N,1.0/Fs)&lt;br /&gt;
    return (fftshift(S),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fs = 100.0&lt;br /&gt;
NW = 3&lt;br /&gt;
(s,t) = sin(f=10.2,Fs=Fs)&lt;br /&gt;
s = s+np.random.randn(len(s))&lt;br /&gt;
(S,F) = mtm(s, NW = NW,  Fs = Fs)&lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.plot( F,fftshift(np.abs(fft(s))**2/len(s) ) ,'g')&lt;br /&gt;
&lt;br /&gt;
print np.sum(S)&lt;br /&gt;
print np.sum(s**2)&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=Nieparametryczne_widmo_mocy&amp;diff=4252</id>
		<title>Nieparametryczne widmo mocy</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=Nieparametryczne_widmo_mocy&amp;diff=4252"/>
		<updated>2015-10-05T19:36:53Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Sygnały stochastyczne */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Widmo mocy==&lt;br /&gt;
=== Moc===&lt;br /&gt;
Moc chwilowa sygnału przez analogię do układów elektrycznych o jednostkowym oporze jest w analizie sygnałów przyjęta jako kwadraty próbek (&amp;lt;math&amp;gt;P = I^2 R = \frac{U^2}{R}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Oznaczmy sygnał &lt;br /&gt;
&amp;lt;math&amp;gt;x[n]&amp;lt;/math&amp;gt;, wówczas jego moc wyraża się wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;P[n]=x[n]^2&amp;lt;/math&amp;gt;, &lt;br /&gt;
a energia wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;E = \sum _n{x[n]^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
==== Zadanie ====&lt;br /&gt;
Przy pomocy funkcji napisanych na poprzednich zajęciach proszę wygenerować sygnał sinusoidalny o amplitudzie 1, częstości 10 Hz, trwający 0.3 sekundy i próbkowany z częstością 1000 Hz. Proszę narysować ten sygnał przy pomocy funkcji &amp;lt;tt&amp;gt;pylab.stem&amp;lt;/tt&amp;gt;, obliczyć i narysować przebieg mocy w czasie, obliczyć energię tego sygnału.&lt;br /&gt;
&lt;br /&gt;
===Widmo mocy: tw. Plancherela i tw. Parsevala ===&lt;br /&gt;
Twierdzenia te omawiane i dowodzone były na [[Szereg_Fouriera#To.C5.BCsamo.C5.9B.C4.87_Parsevala_dla_szereg.C3.B3w_Fouriera|wykładzie]]. Tutaj, tylko krótko przypomnijmy sobie: &lt;br /&gt;
====Twierdzenie Plancherela====&lt;br /&gt;
Jeśli &amp;lt;math&amp;gt;X[k]&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;Y[k]&amp;lt;/math&amp;gt; są transformatami &amp;lt;math&amp;gt;x[n]&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;y[n]&amp;lt;/math&amp;gt; odpowiednio to:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid15&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\sum _{n=0}^{N-1} x[n]y^*[n] = \frac{1}{N} \sum _{k=0}^{N-1} X[k] Y^*[k]&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
gwiazdka oznacza sorzężenie zespolone. &lt;br /&gt;
====Twierdzenie Parsevala====&lt;br /&gt;
jest specjalnym przypadkiem twierdzenia Plancherela:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid16&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\sum _{n=0}^{N-1} \left|x[n]\right|^2 = \frac{1}{N} \sum _{k=0}^{N-1} \left|X[k]\right|^2.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
Twierdzenie to upoważnia nas do utożsamiania kwadratów wartości bezwzględnej składowych transformaty Fouriera z mocą niesioną przez odpowiadające im składowe.&lt;br /&gt;
&lt;br /&gt;
=== Zadanie: funkcja do estymacji widma mocy ===&lt;br /&gt;
Proszę napisać i przetestować funkcję realizującą następujący algorytm estymacji widma mocy:&lt;br /&gt;
# Jako parametry funkcja przyjmuje sygnał &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; i częstość próbkowania tego sygnału&lt;br /&gt;
# Oblicz transformatę Fouriera sygnału przy pomocy &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Unormuj otrzymaną transformatę przez pierwiastek z ilości próbek sygnału&lt;br /&gt;
# Oblicz moc jako iloczyn unormowanej transformaty i jej sprzężenia zespolonego. W pythonie sprzężenie zespolone liczby &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; otrzymujemy korzystając z metody &amp;lt;tt&amp;gt;S.conj()&amp;lt;/tt&amp;gt;. W wyniku powyższego iloczynu dostaniemy liczby zespolone o zerowej części urojonej (proszę to sprawdzić). &lt;br /&gt;
# Do dalszych operacji wybierz tylko część rzeczywistą mocy. Część rzeczywistą liczby zespolonej M pobieramy w następujący sposób: &amp;lt;tt&amp;gt;czesc_rzeczywista_M = M.real&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Korzystając z funkcji &amp;lt;tt&amp;gt;fftfreq&amp;lt;/tt&amp;gt; obliczamy częstości, dla których policzone są współczynniki Fouriera.&lt;br /&gt;
# Przy pomocy funkcji &amp;lt;tt&amp;gt;fftshift&amp;lt;/tt&amp;gt; porządkujemy kolejność wektorów mocy i częstości, tak aby częstości były reprezentowane od -częstości Nyquista, przez 0, do +częstości Nyquista&lt;br /&gt;
# zwracamy uporządkowane wektory mocy i częstości&lt;br /&gt;
&lt;br /&gt;
Testowanie:&lt;br /&gt;
&lt;br /&gt;
# przy pomocy funkcji sin napisanej na drugich ćwiczeniach  wygeneruj sinusoidę o długości 1 s, o częstości 10Hz, próbkowaną 100 Hz.&lt;br /&gt;
# oblicz moc w czasie (trzeba podnieść wartość każdej próbki do kwadratu)&lt;br /&gt;
# oblicz moc w częstości przy pomocy funkcji estymacji widma mocy&lt;br /&gt;
# oblicz energię sygnału w czasie&lt;br /&gt;
# oblicz energię sygnału w częstości&lt;br /&gt;
# wykreśl: &lt;br /&gt;
#* sygnał&lt;br /&gt;
#* przebieg jego mocy w czasie&lt;br /&gt;
#* przebieg mocy w częstości&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import rfft,fft,fftfreq,fftshift&lt;br /&gt;
 &lt;br /&gt;
def widmo_mocy(s, Fs):&lt;br /&gt;
    S = fft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = S*S.conj()&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (fftshift(S_moc),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
(s,t) = sin(f=10,Fs=100.0)&lt;br /&gt;
moc_w_czasie = s**2&lt;br /&gt;
(moc_w_czestosci, F) = widmo_mocy(s, Fs=100.0)&lt;br /&gt;
&lt;br /&gt;
energia_w_czasie = np.sum(moc_w_czasie)&lt;br /&gt;
energia_w_czestosci = np.sum(moc_w_czestosci)&lt;br /&gt;
print 'energia w czasie: ', energia_w_czasie&lt;br /&gt;
print 'energia w czestosci: ', energia_w_czestosci&lt;br /&gt;
&lt;br /&gt;
py.subplot(3,1,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title('Sygnał')&lt;br /&gt;
py.subplot(3,1,2)&lt;br /&gt;
py.plot(t,moc_w_czasie)&lt;br /&gt;
py.title('moc w czasie')&lt;br /&gt;
py.subplot(3,1,3)&lt;br /&gt;
py.plot(F,moc_w_czestosci)&lt;br /&gt;
py.title('moc w częstości')&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===Rozdzielczość widma===&lt;br /&gt;
Proszę zbadać rozdzielczość częstotliwościową widma w zależności od długości sygnału. Używamy funkcji &amp;lt;tt&amp;gt;m_sin&amp;lt;/tt&amp;gt;. Zwrócić uwagę na to co dzieje się na końcach odcinka.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Okienkowanie a widmo mocy: periodogram===&lt;br /&gt;
Przypomnijmy wzór na dyskretną transformatę Fouriera [http://haar.zfb.fuw.edu.pl/edu/index.php/%C4%86wiczenia_2 DFT] zaimplementowaną w FFT: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;S[k] =  \sum_{n=0}^{n-1} s[n] \exp\left\{-2\pi i{nk \over N}\right\}       \qquad k = 0,\ldots,N-1.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Na podstawie twierdzenia [[Nieparametryczne_widmo_mocy#Twierdzenie_Parsevala|Parsevala]] możemy policzyć widmo mocy jako:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P[k] = \frac{1}{N}  \left|S[k]\right|^2 &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeśli do liczenia mocy chcielibyśmy posłużyć się techniką okiennkowania sygnału, to powinniśmy używać okienek znormalizowanych, czyli takich których energia jest równa 1, wtedy mnożenie przez okienko nie zaburzy estymaty energii sygnału. &lt;br /&gt;
&lt;br /&gt;
Aby policzyć widmo mocy sygnału z zastosowaniem okienek wprowadzimy następujące symbole:&lt;br /&gt;
* sygnał: &amp;lt;math&amp;gt;s[n]&amp;lt;/math&amp;gt;&lt;br /&gt;
* okienko: &amp;lt;math&amp;gt; w[n]&amp;lt;/math&amp;gt;&lt;br /&gt;
* okienko znormalizowane: &amp;lt;math&amp;gt; \hat w[n] = \frac{1}{\sqrt{\sum_{n=0}^{N-1} (w[n])^2}}w[n]&amp;lt;/math&amp;gt; &lt;br /&gt;
&amp;lt;!--(w szczególnym przypadku okienka prostokątnego normalizacja ta daje &amp;lt;math&amp;gt;1/N^2&amp;lt;/math&amp;gt; występujące we wzorze na moc)--&amp;gt;&lt;br /&gt;
* widmo mocy sygnału okienkowanego:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P[k] = \frac{1}{\sum_{n=0}^{N-1} (w[n])^2}  \left|\sum_{n=0}^{N-1} s[n]w[n] e^{i\frac{2 \pi }{N} k n}\right|^2 &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Zadanie ====&lt;br /&gt;
Proszę napisać funkcję obliczającą periodogram.&lt;br /&gt;
Funkcja jako argumenty powinna przyjmować sygnał, okno (podane jako sekwencja próbek), i częstość próbkowania. Zwracać powinna widmo mocy i skalę osi częstości. Wewnątrz funkcja powinna implementować liczenie widma z sygnału okienkowanego znormalizowanym oknem.&lt;br /&gt;
&lt;br /&gt;
Funkcję proszę przetestować obliczając dla funkcji sinus energię sygnału w dziedzinie czasu i w dziedzinie częstości. Testy proszę wykonać dla okna prostokątnego, Blackmana i Haminga.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , F_samp):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    F_samp- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 10.1, T =2, Fs = F_samp, phi = 0)&lt;br /&gt;
N = len(x) # dłogość sygnału&lt;br /&gt;
okno = np.ones(N)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N)&lt;br /&gt;
#okno = np.hamming(N)&lt;br /&gt;
&lt;br /&gt;
s = x*okno # sygnał okienkowany&lt;br /&gt;
#&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,x)&lt;br /&gt;
energia_t = np.sum(x**2)&lt;br /&gt;
print 'energia sygnału:', energia_t&lt;br /&gt;
py.title(u' sygnał')&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał')&lt;br /&gt;
py.title(u' sygnał okienkowany ')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
(S,F) = widmo_dB(s,N,F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego')&lt;br /&gt;
py.ylabel('dB')&lt;br /&gt;
&lt;br /&gt;
#periodogram&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
(P, F) = periodogram(x,okno,F_samp)&lt;br /&gt;
py.plot(F,P)&lt;br /&gt;
        &lt;br /&gt;
py.title('periodogram')&lt;br /&gt;
print 'energia periodogramu:', np.sum(P)&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Sygnały stochastyczne ==&lt;br /&gt;
Sygnał stochastyczny to taki sygnał, dla którego ciągu próbek nie da się opisać funkcją czasu. Kolejne próbki w takim sygnale to [[WnioskowanieStatystyczne/Zmienne_losowe_i_generatory_liczb_pseudolosowych#Zmienna_losowa|zmienne losowe]]. Można je opisać podając własności [[WnioskowanieStatystyczne/Zmienne_losowe_i_generatory_liczb_pseudolosowych#Rozk.C5.82ad_prawdopodobie.C5.84stwa|rozkładu]], z k†órego pochodzą. Często w opisie takich zmiennych posługujemy się [[WnioskowanieStatystyczne/Zmienne_losowe_i_generatory_liczb_pseudolosowych#Momenty|momentami rozkładów]].&lt;br /&gt;
Jak można sobie wyobrazić rozkłady, z których pochodzą próbki?&lt;br /&gt;
Można sobie wyobrazić,że obserwowany przez nas sygnał stochastyczny to jedna z możliwych realizacji procesu stochastycznego. &lt;br /&gt;
Jeśli &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; jest zbiorem &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; zdarzeń (&amp;lt;math&amp;gt;k \in K&amp;lt;/math&amp;gt;) i każde z tych zdarzeń ma przypisaną funkcję &amp;lt;math&amp;gt;x_k(t)&amp;lt;/math&amp;gt; zwaną realizacją procesu &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt;, to proces stochastyczny może być zdefiniowany jako zbiór funkcji:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid23&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\xi (t) = \left\lbrace x_1(t),x_2(t),\dots , x_N(t) \right\rbrace &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;x_k(t)&amp;lt;/math&amp;gt; są losowymi funkcjami czasu &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Procesy stochastyczne można opisywać prze wartości oczekiwane liczone po realizacjach.&lt;br /&gt;
&lt;br /&gt;
Dla przypomnienia wartość oczekiwaną liczymy tak:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid24&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
{\mu _x(t_1) = E\left[\xi (t_1) \right]= \lim _{N \rightarrow \infty }\sum _{k=1}^{N}{x_k(t_1)} p(x_k,t_1)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
średnia &amp;lt;math&amp;gt;\mu _x(t_1)&amp;lt;/math&amp;gt; procesu &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt; w chwili &amp;lt;math&amp;gt;t_1&amp;lt;/math&amp;gt; to suma wartośći zaobserwowanych w chwili we wszystkich realizacjach &amp;lt;math&amp;gt;t_1&amp;lt;/math&amp;gt; ważona prawdopodobieństwem wystąpienia tej realizacji:&lt;br /&gt;
=== Stacjonarność i ergodyczność===&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
	&amp;lt;dt&amp;gt;&lt;br /&gt;
	Stacjonarność:&lt;br /&gt;
	&amp;lt;dd&amp;gt;&lt;br /&gt;
	Jeśli dla procesu stochastycznego &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt; wszystkie momenty są niezależne od czasu to jest on stajonarny w ścisłym sensie. Jeśli tylko średnia &amp;lt;math&amp;gt;\mu _x&amp;lt;/math&amp;gt; i autokorelacja &amp;lt;math&amp;gt;R_x(\tau )&amp;lt;/math&amp;gt; nie zależą od czasu to proces jest stacjonarny w słabym sensie, co dla wielu zastosowań jest wystarczające.&lt;br /&gt;
	&amp;lt;dt&amp;gt;&lt;br /&gt;
	Ergodyczność:&lt;br /&gt;
	&amp;lt;dd&amp;gt;&lt;br /&gt;
	Proces jest ergodyczny jeśli jego średnie po czasie i po realizacjach są sobie równe. Oznacza to, że dla takiego procesu jedna realizacja jest reprezentatywna i zawiera całą informację o tym procesie.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Założenie o sygnale, że jest stacjonarny i ergodyczny pozwala zamienić sumowanie po realizacjach na sumowanie po czasie w estymatory momentów statystycznych.&lt;br /&gt;
&lt;br /&gt;
===Transformata Fouriera sygnału stochastycznego===&lt;br /&gt;
Bardzo często musimy oszacować widmo mocy sygnału zawierającego znaczny udział szumu.&lt;br /&gt;
&lt;br /&gt;
Poniższe ćwiczenie ilustruje niepewność szacowania pików w widmie otrzymanym z transformaty Fouriera dla sygnału zawierającego szum.&lt;br /&gt;
&lt;br /&gt;
* wygeneruj 20 realizacji sygnału będącego sumą sinusoidy (f = 20 Hz, T = 1 s, Fs = 100 Hz) i  szumu gaussowskiego&lt;br /&gt;
* dla każdej realizacji oblicz widmo mocy&lt;br /&gt;
* wykreśl wszystkie otrzymane widma na wspólnym wykresie&lt;br /&gt;
&lt;br /&gt;
Proszę obejrzeć otrzymane widma.&lt;br /&gt;
* Zaobserwuj jakiego rzędu jest niepewność wyniku.&lt;br /&gt;
* Czy podobny problem występuje dla sygnału bez szumu?&lt;br /&gt;
* Skonstruuj funkcję rysującą średnie widmo wraz z [[WnioskowanieStatystyczne/_Przedzia%C5%82y_ufno%C5%9Bci|przedziałem ufności]].&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import scipy.stats as st&lt;br /&gt;
&lt;br /&gt;
from numpy.fft import rfft,fft,fftfreq,fftshift&lt;br /&gt;
 &lt;br /&gt;
def widmo_mocy(s, Fs):&lt;br /&gt;
    '''funkcja oblicza widmo mocy sygnału i oś częstości&lt;br /&gt;
    s - sygnał&lt;br /&gt;
    Fs - częstość próbkowania&lt;br /&gt;
    '''&lt;br /&gt;
    S = fft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = S*S.conj()&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (fftshift(S_moc),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def widmo_mocy_rzeczywistego(s,FS):&lt;br /&gt;
    '''funkcja oblicza widmo mocy sygnału rzeczywistego i oś częstości&lt;br /&gt;
    s - sygnał&lt;br /&gt;
    Fs - częstość próbkowania&lt;br /&gt;
&lt;br /&gt;
    zwraca dodatnią część widma&lt;br /&gt;
    '''&lt;br /&gt;
    S = rfft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = np.abs(S)**2&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (S_moc,F)&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def szum(mu =0 , sigma = 1, T = 1, Fs = 128):&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.random.randn(len(t) )*sigma + mu&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def dwadziescia_realizacji(FS):&lt;br /&gt;
    '''&lt;br /&gt;
    *  wygeneruj 20 realizacji sygnału będącego sumą sinusoidy (f=20Hz, T=1s, Fs =100Hz) i szumu gassowskiego&lt;br /&gt;
    * dla każdej realizacji oblicz widmo mocy&lt;br /&gt;
    * wykreśl wszystkie otrzymane widma na wspólnym wykresie &lt;br /&gt;
    '''&lt;br /&gt;
    for i in range(20):&lt;br /&gt;
        (s,t) = sin(f=10,Fs=FS)&lt;br /&gt;
        (sz,t) = szum(Fs =FS)&lt;br /&gt;
        syg = s + sz&lt;br /&gt;
        (moc_w_czestosci, F) = widmo_mocy(syg, Fs=FS)&lt;br /&gt;
        py.plot(F,moc_w_czestosci)&lt;br /&gt;
    py.show()&lt;br /&gt;
    &lt;br /&gt;
def srednie_widmo(FS):&lt;br /&gt;
    '''&lt;br /&gt;
    #  Skonstruuj funkcję rysującą średnie widmo wraz z 95% przedziałem ufności. &lt;br /&gt;
    '''&lt;br /&gt;
    zbior_widm = np.zeros((20,FS))&lt;br /&gt;
    for i in range(20):&lt;br /&gt;
        (s,t) = sin(f=10,Fs=FS)&lt;br /&gt;
        (sz,t) = szum(Fs =FS)&lt;br /&gt;
        syg = s + sz&lt;br /&gt;
        (moc_w_czestosci, F) = widmo_mocy(syg, Fs=FS)&lt;br /&gt;
        zbior_widm[i][:] = moc_w_czestosci&lt;br /&gt;
    srednie_w = np.mean(zbior_widm,axis =0)&lt;br /&gt;
    przedzial_d = np.zeros(len(F))&lt;br /&gt;
    przedzial_g = np.zeros(len(F))&lt;br /&gt;
    for f in F:&lt;br /&gt;
        przedzial_d[f] = st.scoreatpercentile(zbior_widm[:,f], 2.5)&lt;br /&gt;
        przedzial_g[f] = st.scoreatpercentile(zbior_widm[:,f], 97.5)&lt;br /&gt;
    py.plot(F,srednie_w,'r')&lt;br /&gt;
    py.plot(F,przedzial_d,'b')&lt;br /&gt;
    py.plot(F,przedzial_g,'b')&lt;br /&gt;
    py.show()&lt;br /&gt;
&lt;br /&gt;
FS =100.0    &lt;br /&gt;
#dwadziescia_realizacji(FS)&lt;br /&gt;
srednie_widmo(FS)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Oszacowanie błędu transformaty Fouriera dla białego szumu ===&lt;br /&gt;
Dla sygnału stochastycznego &amp;lt;math&amp;gt;x(t)&amp;lt;/math&amp;gt;, którego kolejne próbki pochodzą z niezależnych rozkładów normalnych (biały szum), jego transformata Fouriera &amp;lt;math&amp;gt;X(f)&amp;lt;/math&amp;gt; jest liczbą zespoloną, której część rzeczywista &amp;lt;math&amp;gt;X_R(f)&amp;lt;/math&amp;gt; i urojona &amp;lt;math&amp;gt;X_I(f)&amp;lt;/math&amp;gt; mogą być uznane za nieskorelowane zmienne losowe o średniej zero i równych wariancjach. Ponieważ transformata Fouriera jest operacją liniową więc składowe  &amp;lt;math&amp;gt;X_R(f)&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;X_I(f)&amp;lt;/math&amp;gt; mają rozkłady normalne. Zatem wielkość:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P(f) = |X(f)|^2 = X_R^2(f) + X_I^2(f)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
jest sumą kwadratów dwóch niezależnych zmiennych normalnych. Wielkość ta podlega zatem rozkładowi &amp;lt;math&amp;gt;\chi^2&amp;lt;/math&amp;gt; o dwóch stopniach swobody.&lt;br /&gt;
Możemy oszacować względny błąd &amp;lt;math&amp;gt;P(f_1) &amp;lt;/math&amp;gt; dla danej częstości &amp;lt;math&amp;gt;f_1&amp;lt;/math&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\epsilon_r= \sigma_{P_{f_1}}/\mu_{P_{f_1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dla rozkładu &amp;lt;math&amp;gt;\chi_2^2&amp;lt;/math&amp;gt;:  &amp;lt;math&amp;gt;\sigma^2 = 2n&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;\mu = n&amp;lt;/math&amp;gt;, gdzie &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; jest ilością stopni swobody. W naszym przypadku &amp;lt;math&amp;gt;n =2&amp;lt;/math&amp;gt; więc mamy &amp;lt;math&amp;gt;\epsilon_f = 1&amp;lt;/math&amp;gt;, co oznacza, że dla pojedynczego binu częstości w widmie &amp;lt;math&amp;gt;P(f)&amp;lt;/math&amp;gt; względny błąd wynosi 100%. &lt;br /&gt;
&lt;br /&gt;
Aby zmniejszyć ten błąd trzeba zwiększyć ilość stopni swobody. Są generalnie stosowane dwie techniki. Pierwsza to uśrednianie sąsiednich binów częstości. Otrzymujemy wówczas wygładzony estymator mocy &amp;lt;math&amp;gt;\hat{P}_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\hat{P}_k = \frac{1}{l}[P_k + P_{k+1} + \dots + P_{k+l-1}]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zakładając, że biny częstości  &amp;lt;math&amp;gt;P_i&amp;lt;/math&amp;gt; są niezależne estymator &amp;lt;math&amp;gt;P_k&amp;lt;/math&amp;gt; ma rozkład &amp;lt;math&amp;gt;\chi^2&amp;lt;/math&amp;gt; o ilości stopni swobody równej &amp;lt;math&amp;gt;n= 2l&amp;lt;/math&amp;gt;. Względny błąd takiego estymatora to: &amp;lt;math&amp;gt;\epsilon_r= \sqrt{\frac{1}{l}}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Innym sposobem poprawy estymatora mocy jest podzielenie sygnału na fragmenty, obliczenie periodogramu dla każdego fragmentu, a następnie zsumowanie otrzymanych wartości:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\hat{P}_k=[P_{k,1}+P_{k,2}+\dots+P_{k,j}+\dots+P_{k,q}]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;S_{k,j}&amp;lt;/math&amp;gt; jest estymatą składowej o częstości &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; w oparciu o &amp;lt;math&amp;gt;j-ty&amp;lt;/math&amp;gt; fragment sygnału. Ilość stopni swobody wynosi w tym przypadku &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; zatem względny błąd wynosi: &amp;lt;math&amp;gt;\epsilon_r = \sqrt{\frac{1}{q}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Zauważmy, że w obu metodach zmniejszamy wariancję estymatora kosztem rozdzielczości w częstości.&lt;br /&gt;
&lt;br /&gt;
===Metoda Welcha===&lt;br /&gt;
Proszę napisać i przetestować funkcję implementującą metodę Welcha estymacji widma mocy. Algorytm Welcha:&lt;br /&gt;
# sygnał &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; o długości ''N'' jest dzielony na segmenty, każdy o długości &amp;lt;math&amp;gt;N_s&amp;lt;/math&amp;gt;. Odcinki mogą na siebie zachodzić na &amp;lt;math&amp;gt;N_z&amp;lt;/math&amp;gt; punktów. Czyli są względem siebie przesunięte o &amp;lt;math&amp;gt;N_p = N_s-N_z&amp;lt;/math&amp;gt;.&lt;br /&gt;
# z każdego segmentu liczony jest okienkowany periodogram&lt;br /&gt;
# periodogramy są sumowane&lt;br /&gt;
# wynik dzielony jest przez efektywne wykorzystanie każdego kawałka sygnału w estymacie: &amp;lt;tt&amp;gt;K_eff = dlogosc_okna * ilosc_okien / dlugosc_sygnalu&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funkcję proszę przetestować obliczając dla funkcji sinus energię sygnału w dziedzinie czasu i w dziedzinie częstości. Testy proszę wykonać dla okna prostokątnego, Blackmana i Haminga. &lt;br /&gt;
&lt;br /&gt;
 * &amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
def pwelch(s,okienko, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okienko)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,F_samp)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Całość razem z kodem testującym:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , Fs):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    Fs- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
def pwelch(s,okienko, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okienko)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,Fs)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 3.1, T =20, Fs = F_samp, phi = 0)&lt;br /&gt;
N = len(x) # dłogość sygnału&lt;br /&gt;
&lt;br /&gt;
okno = np.ones(N)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N)&lt;br /&gt;
#okno = np.hamming(N)&lt;br /&gt;
&lt;br /&gt;
s = x*okno # sygnał okienkowany&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
(P, F) = periodogram(x,okno,F_samp)&lt;br /&gt;
py.plot(F,P) &lt;br /&gt;
py.title('periodogram'+' energia: '+ str(np.sum(P)))&lt;br /&gt;
&lt;br /&gt;
#periodogram&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
N_s = N/8&lt;br /&gt;
#okno = np.ones(N_s)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N_s)&lt;br /&gt;
okno = np.hamming(N_s)&lt;br /&gt;
&lt;br /&gt;
         &lt;br /&gt;
(P, F) = pwelch(x,okno,N_s/10,F_samp)&lt;br /&gt;
py.plot(F,P)&lt;br /&gt;
py.title('periodogram Welcha'+' energia: '+ str(np.sum(P)))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Porównanie rozdzielczości i wariancji w periodogramie i w estymatorze Welcha===&lt;br /&gt;
#  wygeneruj 100 realizacji sygnału będącego sumą sinusoidy (f=20Hz, T=10s, Fs =100Hz) i szumu gaussowskiego&lt;br /&gt;
# dla każdej realizacji oblicz widmo mocy za pomocą periodogramu okienkowanego oknem Blackmana&lt;br /&gt;
# wykreśl wszystkie otrzymane widma na wspólnym wykresie (subplot(2,1,1))&lt;br /&gt;
# Powtórz krok 2) dla estymatora Welcha z oknem Blackmana o długości 1/10 długości sygnału przesuwanym co 2 punkty, otrzymane widma wykreśl  na wspólnym wykresie (subplot(2,1,2))&lt;br /&gt;
&lt;br /&gt;
* Co można powiedzieć o rozdzielczości i względnym błędzie obu metod?&lt;br /&gt;
&amp;lt;tt&amp;gt;bl_wzg = np.std(S,axis = 0)/np.mean(S,axis = 0)&amp;lt;/tt&amp;gt; gdzie S jest tablicą zawierającą widma dla każdej z realizacji.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , Fs):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    Fs- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/Fs)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
def pwelch(s,okno, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okno)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,Fs)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&lt;br /&gt;
def realizacja(T,Fs):&lt;br /&gt;
    (x,t) = sin(f = 20.0, T = T, Fs = Fs, phi = 0)&lt;br /&gt;
    x += 2*np.random.randn(len(x))&lt;br /&gt;
    return x&lt;br /&gt;
&lt;br /&gt;
T=10.0&lt;br /&gt;
Fs = 100.0&lt;br /&gt;
N = T*Fs&lt;br /&gt;
Nw = N/10.0&lt;br /&gt;
okno = np.blackman(N)&lt;br /&gt;
okno_welch = np.blackman(Nw)&lt;br /&gt;
&lt;br /&gt;
N_rep = 100&lt;br /&gt;
S_perio = np.zeros((N_rep,N))&lt;br /&gt;
S_welch = np.zeros((N_rep,Nw))&lt;br /&gt;
py.figure(1)&lt;br /&gt;
for i in range(N_rep):&lt;br /&gt;
    s = realizacja(T,Fs)&lt;br /&gt;
    (P, F) = periodogram(s,okno,Fs) &lt;br /&gt;
    S_perio[i] = P&lt;br /&gt;
    py.subplot(2,1,1)&lt;br /&gt;
    py.plot(F,P) &lt;br /&gt;
    (P, F) = pwelch(s,okno_welch,Nw/10,Fs)&lt;br /&gt;
    S_welch[i] = P&lt;br /&gt;
    py.subplot(2,1,2)&lt;br /&gt;
    py.plot(F,P)&lt;br /&gt;
&lt;br /&gt;
py.figure(2)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(np.std(S_perio,axis = 0)/np.mean(S_perio,axis = 0))&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.std(S_welch,axis = 0)/np.mean(S_welch,axis = 0))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Wielookienkowa metoda Thomsona===&lt;br /&gt;
Metoda ta &lt;br /&gt;
[http://ieeexplore.ieee.org/Xplore/login.jsp?url=http%3A%2F%2Fieeexplore.ieee.org%2Fiel5%2F5%2F31317%2F01456701.pdf%3Farnumber%3D1456701&amp;amp;authDecision=-201 Spectrum estimation and harmonic analysis] &lt;br /&gt;
znana jest pod anglojęzyczną nazwą  ''multitaper''. &lt;br /&gt;
&lt;br /&gt;
Można ją opisać poniższym algorytmem:&lt;br /&gt;
* wygeneruj sekwencję ortogonalnych okienek charakteryzujących się minimalnymi wyciekami widma (stosunek energii w piku centralnym do energii w listkach bocznych jest wysoki). Sekwencja takich okien nazywana jest discrete prolate spheroidal sequences (DPSS) lub sekwencją Slepiana.&lt;br /&gt;
* oblicz widmo sygnału okienkowanego każdym z okien w sekwencji&lt;br /&gt;
* uśrednij otrzymane widma&lt;br /&gt;
&lt;br /&gt;
Kolejne dwa zadania służą zapoznaniu się z tą metodą.&lt;br /&gt;
====Własności okienek DPSS ====&lt;br /&gt;
Do generacji sekwencji okienek DPSS wykorzystamy moduł [http://brain.fuw.edu.pl/edu-wiki/images/f/f6/Gendpss.py Gendpss.py]. Proszę go zapisać w swoim katalogu roboczym. &lt;br /&gt;
Importujemy go do naszych programów tak jak każdy inny moduł np.:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import Gendpss as dpss&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Funkcja potrzebna nam z tego modułu to &amp;lt;tt&amp;gt;gendpss()&amp;lt;/tt&amp;gt;. Funkcja ta wytwarza obiekt reprezentujący konkretną sekwencję DPSS. Wywołujemy ją następująco:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
w = dpss.gendpss(N,NW,K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:gdzie: N: długość okna,&lt;br /&gt;
:        NW: iloczyn czas-szerokość pasma&lt;br /&gt;
:        K: ile okien w sekwencji&lt;br /&gt;
Po powyższym wywołaniu obiekt &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; posiada dwie interesujące nas tablice:&lt;br /&gt;
* &amp;lt;tt&amp;gt;w.lambdas&amp;lt;/tt&amp;gt; - to wartości własne okienek. Są one miarą koncentracji energii w piku głównym, jest to zatem miara jakości okienka (dobre okienka mają wartości własne bliskie 1). Zgodnie z teorią takich wartości powinno być 2*NW-1.&lt;br /&gt;
* &amp;lt;tt&amp;gt;w.dpssarray[i]&amp;lt;/tt&amp;gt; - i-te okienko.&lt;br /&gt;
&lt;br /&gt;
=====Polecenia:=====&lt;br /&gt;
Proszę:&lt;br /&gt;
* wygenerować okienka o długości 256, NW = 2. Ilość okien K raz ustalić na 3 (2*NW-1) a drugi raz na 5. Dla ilu okienek ich wartości własne są bliskie 1?&lt;br /&gt;
* narysować przebieg czasowy okienek&lt;br /&gt;
* sprawdzić czy energia okienek jest znormalizowana do 1.&lt;br /&gt;
* sprawdzić czy kolejne okienka są do siebie ortogonalne. W tym celu należy obliczyć iloczyn skalarny pomiędzy kolejnymi okienkami (np.sum(w.dpssarray[i]*w.dpssarray[j])). &lt;br /&gt;
* wywrysować widma okienek analogicznie jak [[%C4%86wiczenia_3#Badanie_w.C5.82asno.C5.9Bci_okien|w tym ćwiczeniu]]&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import gendpss as dpss&lt;br /&gt;
from numpy.fft import fft,fftshift,fftfreq&lt;br /&gt;
&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1.0/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NW = 2&lt;br /&gt;
ile_okien = 5#2*NW-1&lt;br /&gt;
N_okna = 256&lt;br /&gt;
w = dpss.gendpss(N=N_okna,NW=NW,K=ile_okien)&lt;br /&gt;
print 'Wartości własne:'&lt;br /&gt;
print w.lambdas&lt;br /&gt;
&lt;br /&gt;
print 'Wartości iloczynów skalarnych pomiędzy kolejnymi okienekami:'&lt;br /&gt;
py.figure(1)&lt;br /&gt;
for i in range(ile_okien):&lt;br /&gt;
    py.plot(w.dpssarray[i])&lt;br /&gt;
    for j in range(i+1):&lt;br /&gt;
        print np.sum(w.dpssarray[i]*w.dpssarray[j]),&lt;br /&gt;
    print&lt;br /&gt;
&lt;br /&gt;
py.figure(2)&lt;br /&gt;
NFFT = N_okna*4&lt;br /&gt;
S=np.zeros((ile_okien,NFFT))&lt;br /&gt;
for i in range(ile_okien):&lt;br /&gt;
    py.subplot(ile_okien,1,i+1)&lt;br /&gt;
    (S_db, F)= widmo_dB(w.dpssarray[i], NFFT, 1.0)&lt;br /&gt;
    S[i,:]=S_db&lt;br /&gt;
    py.plot(F,S_db)&lt;br /&gt;
    py.ylim((-200,20))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Estymacja widma mocy metodą multitaper ====&lt;br /&gt;
Proszę napisać funkcję do estymacji mocy metodą multitaper.&lt;br /&gt;
Funkcja powinna pobierać następujące argumenty: sygnał, iloczyn NW, częstość próbkowania sygnału. Funkcja powinna zwracać krotkę &amp;lt;tt&amp;gt;(S,F)&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; widmo mocy, &amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt; skala częstości.&lt;br /&gt;
Przykładowe wywołanie takiej funkcji powinno wyglądać tak:&lt;br /&gt;
&amp;lt;tt&amp;gt; (S,F) = mtm(s,  NW = 3, Fs = 128)&amp;lt;/tt&amp;gt;&lt;br /&gt;
Algorytm do zastosowania wewnątrz funkcji:&lt;br /&gt;
# Oblicz maksymalną liczbę okienek &amp;lt;tt&amp;gt; K = 2*NW-1&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Oblicz długość sygnału&lt;br /&gt;
# wygeneruj serię okienek dpss&lt;br /&gt;
# dla każdego z otrzymanych okienek oblicz widmo mocy iloczynu tego okienka i sygnału. Dla i-tego okienka będzie to: &amp;lt;tt&amp;gt;Si = np.abs(fft(s*w.dpssarray[i]))**2&amp;lt;/tt&amp;gt;&lt;br /&gt;
# uśrednij widma otrzymane dla wszystkich okienek&lt;br /&gt;
# wygeneruj oś częstości (&amp;lt;tt&amp;gt;fftfreq&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Działanie funkcji sprawdź estymując i wykreślając widmo sinusoidy np. o częstości 10 Hz, czasie trwania 1s, próbkowanej 100Hz z dodanym szumem gaussowskim o średniej 0 i wariancji 1. Sprawdź także zachowanie energii przez tą estymatę. Dla porównania na tym samym wykresie dorysuj widmo otrzymane przez [[Nieparametryczne_widmo_mocy#Okienkowanie_a_widmo_mocy:_periodogram|periodogram]] z oknem prostokątnym.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import gendpss as dpss&lt;br /&gt;
from numpy.fft import fft,fftshift,fftfreq&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def mtm(s, NW = 3, Fs = 128):&lt;br /&gt;
    '''estymacja widma w oparciu o  metodę Multiteper &lt;br /&gt;
    D. J. Thomson, “Spectrum Estimation and Harmonic Analysis,” Proceedings of the&lt;br /&gt;
    IEEE, vol. 70, no. 9, pp. 1055 – 1096, 1982.&lt;br /&gt;
    x - sygnał&lt;br /&gt;
    N -ilość punktów okna&lt;br /&gt;
    NW - iloczyn długości okna w czasie i szerokości w częstości&lt;br /&gt;
    K - ilość okien&lt;br /&gt;
&lt;br /&gt;
    funkcja zwraca estymatę mocy widmowej&lt;br /&gt;
    '''&lt;br /&gt;
    K = 2*NW-1&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    w = dpss.gendpss(N,NW,K)&lt;br /&gt;
    S=np.zeros(N)&lt;br /&gt;
    for i in range(K):&lt;br /&gt;
        Si = np.abs(fft(s*w.dpssarray[i]))**2&lt;br /&gt;
        S[:] += Si.real&lt;br /&gt;
    S = S/K&lt;br /&gt;
    F = fftfreq(N,1.0/Fs)&lt;br /&gt;
    return (fftshift(S),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fs = 100.0&lt;br /&gt;
NW = 3&lt;br /&gt;
(s,t) = sin(f=10.2,Fs=Fs)&lt;br /&gt;
s = s+np.random.randn(len(s))&lt;br /&gt;
(S,F) = mtm(s, NW = NW,  Fs = Fs)&lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.plot( F,fftshift(np.abs(fft(s))**2/len(s) ) ,'g')&lt;br /&gt;
&lt;br /&gt;
print np.sum(S)&lt;br /&gt;
print np.sum(s**2)&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=Nieparametryczne_widmo_mocy&amp;diff=4251</id>
		<title>Nieparametryczne widmo mocy</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=Nieparametryczne_widmo_mocy&amp;diff=4251"/>
		<updated>2015-10-05T19:20:10Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Transformata Fouriera sygnału stochastycznego */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Widmo mocy==&lt;br /&gt;
=== Moc===&lt;br /&gt;
Moc chwilowa sygnału przez analogię do układów elektrycznych o jednostkowym oporze jest w analizie sygnałów przyjęta jako kwadraty próbek (&amp;lt;math&amp;gt;P = I^2 R = \frac{U^2}{R}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Oznaczmy sygnał &lt;br /&gt;
&amp;lt;math&amp;gt;x[n]&amp;lt;/math&amp;gt;, wówczas jego moc wyraża się wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;P[n]=x[n]^2&amp;lt;/math&amp;gt;, &lt;br /&gt;
a energia wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;E = \sum _n{x[n]^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
==== Zadanie ====&lt;br /&gt;
Przy pomocy funkcji napisanych na poprzednich zajęciach proszę wygenerować sygnał sinusoidalny o amplitudzie 1, częstości 10 Hz, trwający 0.3 sekundy i próbkowany z częstością 1000 Hz. Proszę narysować ten sygnał przy pomocy funkcji &amp;lt;tt&amp;gt;pylab.stem&amp;lt;/tt&amp;gt;, obliczyć i narysować przebieg mocy w czasie, obliczyć energię tego sygnału.&lt;br /&gt;
&lt;br /&gt;
===Widmo mocy: tw. Plancherela i tw. Parsevala ===&lt;br /&gt;
Twierdzenia te omawiane i dowodzone były na [[Szereg_Fouriera#To.C5.BCsamo.C5.9B.C4.87_Parsevala_dla_szereg.C3.B3w_Fouriera|wykładzie]]. Tutaj, tylko krótko przypomnijmy sobie: &lt;br /&gt;
====Twierdzenie Plancherela====&lt;br /&gt;
Jeśli &amp;lt;math&amp;gt;X[k]&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;Y[k]&amp;lt;/math&amp;gt; są transformatami &amp;lt;math&amp;gt;x[n]&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;y[n]&amp;lt;/math&amp;gt; odpowiednio to:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid15&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\sum _{n=0}^{N-1} x[n]y^*[n] = \frac{1}{N} \sum _{k=0}^{N-1} X[k] Y^*[k]&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
gwiazdka oznacza sorzężenie zespolone. &lt;br /&gt;
====Twierdzenie Parsevala====&lt;br /&gt;
jest specjalnym przypadkiem twierdzenia Plancherela:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid16&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\sum _{n=0}^{N-1} \left|x[n]\right|^2 = \frac{1}{N} \sum _{k=0}^{N-1} \left|X[k]\right|^2.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
Twierdzenie to upoważnia nas do utożsamiania kwadratów wartości bezwzględnej składowych transformaty Fouriera z mocą niesioną przez odpowiadające im składowe.&lt;br /&gt;
&lt;br /&gt;
=== Zadanie: funkcja do estymacji widma mocy ===&lt;br /&gt;
Proszę napisać i przetestować funkcję realizującą następujący algorytm estymacji widma mocy:&lt;br /&gt;
# Jako parametry funkcja przyjmuje sygnał &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; i częstość próbkowania tego sygnału&lt;br /&gt;
# Oblicz transformatę Fouriera sygnału przy pomocy &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Unormuj otrzymaną transformatę przez pierwiastek z ilości próbek sygnału&lt;br /&gt;
# Oblicz moc jako iloczyn unormowanej transformaty i jej sprzężenia zespolonego. W pythonie sprzężenie zespolone liczby &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; otrzymujemy korzystając z metody &amp;lt;tt&amp;gt;S.conj()&amp;lt;/tt&amp;gt;. W wyniku powyższego iloczynu dostaniemy liczby zespolone o zerowej części urojonej (proszę to sprawdzić). &lt;br /&gt;
# Do dalszych operacji wybierz tylko część rzeczywistą mocy. Część rzeczywistą liczby zespolonej M pobieramy w następujący sposób: &amp;lt;tt&amp;gt;czesc_rzeczywista_M = M.real&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Korzystając z funkcji &amp;lt;tt&amp;gt;fftfreq&amp;lt;/tt&amp;gt; obliczamy częstości, dla których policzone są współczynniki Fouriera.&lt;br /&gt;
# Przy pomocy funkcji &amp;lt;tt&amp;gt;fftshift&amp;lt;/tt&amp;gt; porządkujemy kolejność wektorów mocy i częstości, tak aby częstości były reprezentowane od -częstości Nyquista, przez 0, do +częstości Nyquista&lt;br /&gt;
# zwracamy uporządkowane wektory mocy i częstości&lt;br /&gt;
&lt;br /&gt;
Testowanie:&lt;br /&gt;
&lt;br /&gt;
# przy pomocy funkcji sin napisanej na drugich ćwiczeniach  wygeneruj sinusoidę o długości 1 s, o częstości 10Hz, próbkowaną 100 Hz.&lt;br /&gt;
# oblicz moc w czasie (trzeba podnieść wartość każdej próbki do kwadratu)&lt;br /&gt;
# oblicz moc w częstości przy pomocy funkcji estymacji widma mocy&lt;br /&gt;
# oblicz energię sygnału w czasie&lt;br /&gt;
# oblicz energię sygnału w częstości&lt;br /&gt;
# wykreśl: &lt;br /&gt;
#* sygnał&lt;br /&gt;
#* przebieg jego mocy w czasie&lt;br /&gt;
#* przebieg mocy w częstości&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import rfft,fft,fftfreq,fftshift&lt;br /&gt;
 &lt;br /&gt;
def widmo_mocy(s, Fs):&lt;br /&gt;
    S = fft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = S*S.conj()&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (fftshift(S_moc),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
(s,t) = sin(f=10,Fs=100.0)&lt;br /&gt;
moc_w_czasie = s**2&lt;br /&gt;
(moc_w_czestosci, F) = widmo_mocy(s, Fs=100.0)&lt;br /&gt;
&lt;br /&gt;
energia_w_czasie = np.sum(moc_w_czasie)&lt;br /&gt;
energia_w_czestosci = np.sum(moc_w_czestosci)&lt;br /&gt;
print 'energia w czasie: ', energia_w_czasie&lt;br /&gt;
print 'energia w czestosci: ', energia_w_czestosci&lt;br /&gt;
&lt;br /&gt;
py.subplot(3,1,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title('Sygnał')&lt;br /&gt;
py.subplot(3,1,2)&lt;br /&gt;
py.plot(t,moc_w_czasie)&lt;br /&gt;
py.title('moc w czasie')&lt;br /&gt;
py.subplot(3,1,3)&lt;br /&gt;
py.plot(F,moc_w_czestosci)&lt;br /&gt;
py.title('moc w częstości')&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===Rozdzielczość widma===&lt;br /&gt;
Proszę zbadać rozdzielczość częstotliwościową widma w zależności od długości sygnału. Używamy funkcji &amp;lt;tt&amp;gt;m_sin&amp;lt;/tt&amp;gt;. Zwrócić uwagę na to co dzieje się na końcach odcinka.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Okienkowanie a widmo mocy: periodogram===&lt;br /&gt;
Przypomnijmy wzór na dyskretną transformatę Fouriera [http://haar.zfb.fuw.edu.pl/edu/index.php/%C4%86wiczenia_2 DFT] zaimplementowaną w FFT: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;S[k] =  \sum_{n=0}^{n-1} s[n] \exp\left\{-2\pi i{nk \over N}\right\}       \qquad k = 0,\ldots,N-1.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Na podstawie twierdzenia [[Nieparametryczne_widmo_mocy#Twierdzenie_Parsevala|Parsevala]] możemy policzyć widmo mocy jako:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P[k] = \frac{1}{N}  \left|S[k]\right|^2 &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeśli do liczenia mocy chcielibyśmy posłużyć się techniką okiennkowania sygnału, to powinniśmy używać okienek znormalizowanych, czyli takich których energia jest równa 1, wtedy mnożenie przez okienko nie zaburzy estymaty energii sygnału. &lt;br /&gt;
&lt;br /&gt;
Aby policzyć widmo mocy sygnału z zastosowaniem okienek wprowadzimy następujące symbole:&lt;br /&gt;
* sygnał: &amp;lt;math&amp;gt;s[n]&amp;lt;/math&amp;gt;&lt;br /&gt;
* okienko: &amp;lt;math&amp;gt; w[n]&amp;lt;/math&amp;gt;&lt;br /&gt;
* okienko znormalizowane: &amp;lt;math&amp;gt; \hat w[n] = \frac{1}{\sqrt{\sum_{n=0}^{N-1} (w[n])^2}}w[n]&amp;lt;/math&amp;gt; &lt;br /&gt;
&amp;lt;!--(w szczególnym przypadku okienka prostokątnego normalizacja ta daje &amp;lt;math&amp;gt;1/N^2&amp;lt;/math&amp;gt; występujące we wzorze na moc)--&amp;gt;&lt;br /&gt;
* widmo mocy sygnału okienkowanego:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P[k] = \frac{1}{\sum_{n=0}^{N-1} (w[n])^2}  \left|\sum_{n=0}^{N-1} s[n]w[n] e^{i\frac{2 \pi }{N} k n}\right|^2 &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Zadanie ====&lt;br /&gt;
Proszę napisać funkcję obliczającą periodogram.&lt;br /&gt;
Funkcja jako argumenty powinna przyjmować sygnał, okno (podane jako sekwencja próbek), i częstość próbkowania. Zwracać powinna widmo mocy i skalę osi częstości. Wewnątrz funkcja powinna implementować liczenie widma z sygnału okienkowanego znormalizowanym oknem.&lt;br /&gt;
&lt;br /&gt;
Funkcję proszę przetestować obliczając dla funkcji sinus energię sygnału w dziedzinie czasu i w dziedzinie częstości. Testy proszę wykonać dla okna prostokątnego, Blackmana i Haminga.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , F_samp):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    F_samp- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 10.1, T =2, Fs = F_samp, phi = 0)&lt;br /&gt;
N = len(x) # dłogość sygnału&lt;br /&gt;
okno = np.ones(N)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N)&lt;br /&gt;
#okno = np.hamming(N)&lt;br /&gt;
&lt;br /&gt;
s = x*okno # sygnał okienkowany&lt;br /&gt;
#&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,x)&lt;br /&gt;
energia_t = np.sum(x**2)&lt;br /&gt;
print 'energia sygnału:', energia_t&lt;br /&gt;
py.title(u' sygnał')&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał')&lt;br /&gt;
py.title(u' sygnał okienkowany ')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
(S,F) = widmo_dB(s,N,F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego')&lt;br /&gt;
py.ylabel('dB')&lt;br /&gt;
&lt;br /&gt;
#periodogram&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
(P, F) = periodogram(x,okno,F_samp)&lt;br /&gt;
py.plot(F,P)&lt;br /&gt;
        &lt;br /&gt;
py.title('periodogram')&lt;br /&gt;
print 'energia periodogramu:', np.sum(P)&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Sygnały stochastyczne ==&lt;br /&gt;
Sygnał stochastyczny to taki sygnał, dla którego ciągu próbek nie da się opisać funkcją czasu. Kolejne próbki w takim sygnale to [[Zmienne_losowe_i_generatory_liczb_pseudolosowych#Zmienna_losowa|zmienne losowe]]. Można je opisać podając własności [[Zmienne_losowe_i_generatory_liczb_pseudolosowych#Rozk.C5.82ad_prawdopodobie.C5.84stwa|rozkładu]], z k†órego pochodzą. Często w opisie takich zmiennych posługujemy się [[WnioskowanieStatystyczne/Zmienne_losowe_i_generatory_liczb_pseudolosowych#Momenty|momentami rozkładów]].&lt;br /&gt;
Jak można sobie wyobrazić rozkłady, z których pochodzą próbki?&lt;br /&gt;
Można sobie wyobrazić,że obserwowany przez nas sygnał stochastyczny to jedna z możliwych realizacji procesu stochastycznego. &lt;br /&gt;
Jeśli &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; jest zbiorem &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; zdarzeń (&amp;lt;math&amp;gt;k \in K&amp;lt;/math&amp;gt;) i każde z tych zdarzeń ma przypisaną funkcję &amp;lt;math&amp;gt;x_k(t)&amp;lt;/math&amp;gt; zwaną realizacją procesu &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt;, to proces stochastyczny może być zdefiniowany jako zbiór funkcji:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid23&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\xi (t) = \left\lbrace x_1(t),x_2(t),\dots , x_N(t) \right\rbrace &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;x_k(t)&amp;lt;/math&amp;gt; są losowymi funkcjami czasu &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Procesy stochastyczne można opisywać prze wartości oczekiwane liczone po realizacjach.&lt;br /&gt;
&lt;br /&gt;
Dla przypomnienia wartość oczekiwaną liczymy tak:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid24&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
{\mu _x(t_1) = E\left[\xi (t_1) \right]= \lim _{N \rightarrow \infty }\sum _{k=1}^{N}{x_k(t_1)} p(x_k,t_1)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
średnia &amp;lt;math&amp;gt;\mu _x(t_1)&amp;lt;/math&amp;gt; procesu &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt; w chwili &amp;lt;math&amp;gt;t_1&amp;lt;/math&amp;gt; to suma wartośći zaobserwowanych w chwili we wszystkich realizacjach &amp;lt;math&amp;gt;t_1&amp;lt;/math&amp;gt; ważona prawdopodobieństwem wystąpienia tej realizacji:&lt;br /&gt;
=== Stacjonarność i ergodyczność===&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
	&amp;lt;dt&amp;gt;&lt;br /&gt;
	Stacjonarność:&lt;br /&gt;
	&amp;lt;dd&amp;gt;&lt;br /&gt;
	Jeśli dla procesu stochastycznego &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt; wszystkie momenty są niezależne od czasu to jest on stajonarny w ścisłym sensie. Jeśli tylko średnia &amp;lt;math&amp;gt;\mu _x&amp;lt;/math&amp;gt; i autokorelacja &amp;lt;math&amp;gt;R_x(\tau )&amp;lt;/math&amp;gt; nie zależą od czasu to proces jest stacjonarny w słabym sensie, co dla wielu zastosowań jest wystarczające.&lt;br /&gt;
	&amp;lt;dt&amp;gt;&lt;br /&gt;
	Ergodyczność:&lt;br /&gt;
	&amp;lt;dd&amp;gt;&lt;br /&gt;
	Proces jest ergodyczny jeśli jego średnie po czasie i po realizacjach są sobie równe. Oznacza to, że dla takiego procesu jedna realizacja jest reprezentatywna i zawiera całą informację o tym procesie.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Założenie o sygnale, że jest stacjonarny i ergodyczny pozwala zamienić sumowanie po realizacjach na sumowanie po czasie w estymatory momentów statystycznych.&lt;br /&gt;
&lt;br /&gt;
===Transformata Fouriera sygnału stochastycznego===&lt;br /&gt;
Bardzo często musimy oszacować widmo mocy sygnału zawierającego znaczny udział szumu.&lt;br /&gt;
&lt;br /&gt;
Poniższe ćwiczenie ilustruje niepewność szacowania pików w widmie otrzymanym z transformaty Fouriera dla sygnału zawierającego szum.&lt;br /&gt;
&lt;br /&gt;
* wygeneruj 20 realizacji sygnału będącego sumą sinusoidy (f = 20 Hz, T = 1 s, Fs = 100 Hz) i  szumu gaussowskiego&lt;br /&gt;
* dla każdej realizacji oblicz widmo mocy&lt;br /&gt;
* wykreśl wszystkie otrzymane widma na wspólnym wykresie&lt;br /&gt;
&lt;br /&gt;
Proszę obejrzeć otrzymane widma.&lt;br /&gt;
* Zaobserwuj jakiego rzędu jest niepewność wyniku.&lt;br /&gt;
* Czy podobny problem występuje dla sygnału bez szumu?&lt;br /&gt;
* Skonstruuj funkcję rysującą średnie widmo wraz z [[WnioskowanieStatystyczne/_Przedzia%C5%82y_ufno%C5%9Bci|przedziałem ufności]].&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import scipy.stats as st&lt;br /&gt;
&lt;br /&gt;
from numpy.fft import rfft,fft,fftfreq,fftshift&lt;br /&gt;
 &lt;br /&gt;
def widmo_mocy(s, Fs):&lt;br /&gt;
    '''funkcja oblicza widmo mocy sygnału i oś częstości&lt;br /&gt;
    s - sygnał&lt;br /&gt;
    Fs - częstość próbkowania&lt;br /&gt;
    '''&lt;br /&gt;
    S = fft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = S*S.conj()&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (fftshift(S_moc),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def widmo_mocy_rzeczywistego(s,FS):&lt;br /&gt;
    '''funkcja oblicza widmo mocy sygnału rzeczywistego i oś częstości&lt;br /&gt;
    s - sygnał&lt;br /&gt;
    Fs - częstość próbkowania&lt;br /&gt;
&lt;br /&gt;
    zwraca dodatnią część widma&lt;br /&gt;
    '''&lt;br /&gt;
    S = rfft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = np.abs(S)**2&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (S_moc,F)&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def szum(mu =0 , sigma = 1, T = 1, Fs = 128):&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.random.randn(len(t) )*sigma + mu&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def dwadziescia_realizacji(FS):&lt;br /&gt;
    '''&lt;br /&gt;
    *  wygeneruj 20 realizacji sygnału będącego sumą sinusoidy (f=20Hz, T=1s, Fs =100Hz) i szumu gassowskiego&lt;br /&gt;
    * dla każdej realizacji oblicz widmo mocy&lt;br /&gt;
    * wykreśl wszystkie otrzymane widma na wspólnym wykresie &lt;br /&gt;
    '''&lt;br /&gt;
    for i in range(20):&lt;br /&gt;
        (s,t) = sin(f=10,Fs=FS)&lt;br /&gt;
        (sz,t) = szum(Fs =FS)&lt;br /&gt;
        syg = s + sz&lt;br /&gt;
        (moc_w_czestosci, F) = widmo_mocy(syg, Fs=FS)&lt;br /&gt;
        py.plot(F,moc_w_czestosci)&lt;br /&gt;
    py.show()&lt;br /&gt;
    &lt;br /&gt;
def srednie_widmo(FS):&lt;br /&gt;
    '''&lt;br /&gt;
    #  Skonstruuj funkcję rysującą średnie widmo wraz z 95% przedziałem ufności. &lt;br /&gt;
    '''&lt;br /&gt;
    zbior_widm = np.zeros((20,FS))&lt;br /&gt;
    for i in range(20):&lt;br /&gt;
        (s,t) = sin(f=10,Fs=FS)&lt;br /&gt;
        (sz,t) = szum(Fs =FS)&lt;br /&gt;
        syg = s + sz&lt;br /&gt;
        (moc_w_czestosci, F) = widmo_mocy(syg, Fs=FS)&lt;br /&gt;
        zbior_widm[i][:] = moc_w_czestosci&lt;br /&gt;
    srednie_w = np.mean(zbior_widm,axis =0)&lt;br /&gt;
    przedzial_d = np.zeros(len(F))&lt;br /&gt;
    przedzial_g = np.zeros(len(F))&lt;br /&gt;
    for f in F:&lt;br /&gt;
        przedzial_d[f] = st.scoreatpercentile(zbior_widm[:,f], 2.5)&lt;br /&gt;
        przedzial_g[f] = st.scoreatpercentile(zbior_widm[:,f], 97.5)&lt;br /&gt;
    py.plot(F,srednie_w,'r')&lt;br /&gt;
    py.plot(F,przedzial_d,'b')&lt;br /&gt;
    py.plot(F,przedzial_g,'b')&lt;br /&gt;
    py.show()&lt;br /&gt;
&lt;br /&gt;
FS =100.0    &lt;br /&gt;
#dwadziescia_realizacji(FS)&lt;br /&gt;
srednie_widmo(FS)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Oszacowanie błędu transformaty Fouriera dla białego szumu ===&lt;br /&gt;
Dla sygnału stochastycznego &amp;lt;math&amp;gt;x(t)&amp;lt;/math&amp;gt;, którego kolejne próbki pochodzą z niezależnych rozkładów normalnych (biały szum), jego transformata Fouriera &amp;lt;math&amp;gt;X(f)&amp;lt;/math&amp;gt; jest liczbą zespoloną, której część rzeczywista &amp;lt;math&amp;gt;X_R(f)&amp;lt;/math&amp;gt; i urojona &amp;lt;math&amp;gt;X_I(f)&amp;lt;/math&amp;gt; mogą być uznane za nieskorelowane zmienne losowe o średniej zero i równych wariancjach. Ponieważ transformata Fouriera jest operacją liniową więc składowe  &amp;lt;math&amp;gt;X_R(f)&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;X_I(f)&amp;lt;/math&amp;gt; mają rozkłady normalne. Zatem wielkość:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P(f) = |X(f)|^2 = X_R^2(f) + X_I^2(f)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
jest sumą kwadratów dwóch niezależnych zmiennych normalnych. Wielkość ta podlega zatem rozkładowi &amp;lt;math&amp;gt;\chi^2&amp;lt;/math&amp;gt; o dwóch stopniach swobody.&lt;br /&gt;
Możemy oszacować względny błąd &amp;lt;math&amp;gt;P(f_1) &amp;lt;/math&amp;gt; dla danej częstości &amp;lt;math&amp;gt;f_1&amp;lt;/math&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\epsilon_r= \sigma_{P_{f_1}}/\mu_{P_{f_1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dla rozkładu &amp;lt;math&amp;gt;\chi_2^2&amp;lt;/math&amp;gt;:  &amp;lt;math&amp;gt;\sigma^2 = 2n&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;\mu = n&amp;lt;/math&amp;gt;, gdzie &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; jest ilością stopni swobody. W naszym przypadku &amp;lt;math&amp;gt;n =2&amp;lt;/math&amp;gt; więc mamy &amp;lt;math&amp;gt;\epsilon_f = 1&amp;lt;/math&amp;gt;, co oznacza, że dla pojedynczego binu częstości w widmie &amp;lt;math&amp;gt;P(f)&amp;lt;/math&amp;gt; względny błąd wynosi 100%. &lt;br /&gt;
&lt;br /&gt;
Aby zmniejszyć ten błąd trzeba zwiększyć ilość stopni swobody. Są generalnie stosowane dwie techniki. Pierwsza to uśrednianie sąsiednich binów częstości. Otrzymujemy wówczas wygładzony estymator mocy &amp;lt;math&amp;gt;\hat{P}_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\hat{P}_k = \frac{1}{l}[P_k + P_{k+1} + \dots + P_{k+l-1}]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zakładając, że biny częstości  &amp;lt;math&amp;gt;P_i&amp;lt;/math&amp;gt; są niezależne estymator &amp;lt;math&amp;gt;P_k&amp;lt;/math&amp;gt; ma rozkład &amp;lt;math&amp;gt;\chi^2&amp;lt;/math&amp;gt; o ilości stopni swobody równej &amp;lt;math&amp;gt;n= 2l&amp;lt;/math&amp;gt;. Względny błąd takiego estymatora to: &amp;lt;math&amp;gt;\epsilon_r= \sqrt{\frac{1}{l}}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Innym sposobem poprawy estymatora mocy jest podzielenie sygnału na fragmenty, obliczenie periodogramu dla każdego fragmentu, a następnie zsumowanie otrzymanych wartości:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\hat{P}_k=[P_{k,1}+P_{k,2}+\dots+P_{k,j}+\dots+P_{k,q}]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;S_{k,j}&amp;lt;/math&amp;gt; jest estymatą składowej o częstości &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; w oparciu o &amp;lt;math&amp;gt;j-ty&amp;lt;/math&amp;gt; fragment sygnału. Ilość stopni swobody wynosi w tym przypadku &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; zatem względny błąd wynosi: &amp;lt;math&amp;gt;\epsilon_r = \sqrt{\frac{1}{q}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Zauważmy, że w obu metodach zmniejszamy wariancję estymatora kosztem rozdzielczości w częstości.&lt;br /&gt;
&lt;br /&gt;
===Metoda Welcha===&lt;br /&gt;
Proszę napisać i przetestować funkcję implementującą metodę Welcha estymacji widma mocy. Algorytm Welcha:&lt;br /&gt;
# sygnał &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; o długości ''N'' jest dzielony na segmenty, każdy o długości &amp;lt;math&amp;gt;N_s&amp;lt;/math&amp;gt;. Odcinki mogą na siebie zachodzić na &amp;lt;math&amp;gt;N_z&amp;lt;/math&amp;gt; punktów. Czyli są względem siebie przesunięte o &amp;lt;math&amp;gt;N_p = N_s-N_z&amp;lt;/math&amp;gt;.&lt;br /&gt;
# z każdego segmentu liczony jest okienkowany periodogram&lt;br /&gt;
# periodogramy są sumowane&lt;br /&gt;
# wynik dzielony jest przez efektywne wykorzystanie każdego kawałka sygnału w estymacie: &amp;lt;tt&amp;gt;K_eff = dlogosc_okna * ilosc_okien / dlugosc_sygnalu&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funkcję proszę przetestować obliczając dla funkcji sinus energię sygnału w dziedzinie czasu i w dziedzinie częstości. Testy proszę wykonać dla okna prostokątnego, Blackmana i Haminga. &lt;br /&gt;
&lt;br /&gt;
 * &amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
def pwelch(s,okienko, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okienko)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,F_samp)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Całość razem z kodem testującym:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , Fs):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    Fs- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
def pwelch(s,okienko, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okienko)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,Fs)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 3.1, T =20, Fs = F_samp, phi = 0)&lt;br /&gt;
N = len(x) # dłogość sygnału&lt;br /&gt;
&lt;br /&gt;
okno = np.ones(N)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N)&lt;br /&gt;
#okno = np.hamming(N)&lt;br /&gt;
&lt;br /&gt;
s = x*okno # sygnał okienkowany&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
(P, F) = periodogram(x,okno,F_samp)&lt;br /&gt;
py.plot(F,P) &lt;br /&gt;
py.title('periodogram'+' energia: '+ str(np.sum(P)))&lt;br /&gt;
&lt;br /&gt;
#periodogram&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
N_s = N/8&lt;br /&gt;
#okno = np.ones(N_s)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N_s)&lt;br /&gt;
okno = np.hamming(N_s)&lt;br /&gt;
&lt;br /&gt;
         &lt;br /&gt;
(P, F) = pwelch(x,okno,N_s/10,F_samp)&lt;br /&gt;
py.plot(F,P)&lt;br /&gt;
py.title('periodogram Welcha'+' energia: '+ str(np.sum(P)))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Porównanie rozdzielczości i wariancji w periodogramie i w estymatorze Welcha===&lt;br /&gt;
#  wygeneruj 100 realizacji sygnału będącego sumą sinusoidy (f=20Hz, T=10s, Fs =100Hz) i szumu gaussowskiego&lt;br /&gt;
# dla każdej realizacji oblicz widmo mocy za pomocą periodogramu okienkowanego oknem Blackmana&lt;br /&gt;
# wykreśl wszystkie otrzymane widma na wspólnym wykresie (subplot(2,1,1))&lt;br /&gt;
# Powtórz krok 2) dla estymatora Welcha z oknem Blackmana o długości 1/10 długości sygnału przesuwanym co 2 punkty, otrzymane widma wykreśl  na wspólnym wykresie (subplot(2,1,2))&lt;br /&gt;
&lt;br /&gt;
* Co można powiedzieć o rozdzielczości i względnym błędzie obu metod?&lt;br /&gt;
&amp;lt;tt&amp;gt;bl_wzg = np.std(S,axis = 0)/np.mean(S,axis = 0)&amp;lt;/tt&amp;gt; gdzie S jest tablicą zawierającą widma dla każdej z realizacji.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , Fs):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    Fs- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/Fs)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
def pwelch(s,okno, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okno)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,Fs)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&lt;br /&gt;
def realizacja(T,Fs):&lt;br /&gt;
    (x,t) = sin(f = 20.0, T = T, Fs = Fs, phi = 0)&lt;br /&gt;
    x += 2*np.random.randn(len(x))&lt;br /&gt;
    return x&lt;br /&gt;
&lt;br /&gt;
T=10.0&lt;br /&gt;
Fs = 100.0&lt;br /&gt;
N = T*Fs&lt;br /&gt;
Nw = N/10.0&lt;br /&gt;
okno = np.blackman(N)&lt;br /&gt;
okno_welch = np.blackman(Nw)&lt;br /&gt;
&lt;br /&gt;
N_rep = 100&lt;br /&gt;
S_perio = np.zeros((N_rep,N))&lt;br /&gt;
S_welch = np.zeros((N_rep,Nw))&lt;br /&gt;
py.figure(1)&lt;br /&gt;
for i in range(N_rep):&lt;br /&gt;
    s = realizacja(T,Fs)&lt;br /&gt;
    (P, F) = periodogram(s,okno,Fs) &lt;br /&gt;
    S_perio[i] = P&lt;br /&gt;
    py.subplot(2,1,1)&lt;br /&gt;
    py.plot(F,P) &lt;br /&gt;
    (P, F) = pwelch(s,okno_welch,Nw/10,Fs)&lt;br /&gt;
    S_welch[i] = P&lt;br /&gt;
    py.subplot(2,1,2)&lt;br /&gt;
    py.plot(F,P)&lt;br /&gt;
&lt;br /&gt;
py.figure(2)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(np.std(S_perio,axis = 0)/np.mean(S_perio,axis = 0))&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.std(S_welch,axis = 0)/np.mean(S_welch,axis = 0))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Wielookienkowa metoda Thomsona===&lt;br /&gt;
Metoda ta &lt;br /&gt;
[http://ieeexplore.ieee.org/Xplore/login.jsp?url=http%3A%2F%2Fieeexplore.ieee.org%2Fiel5%2F5%2F31317%2F01456701.pdf%3Farnumber%3D1456701&amp;amp;authDecision=-201 Spectrum estimation and harmonic analysis] &lt;br /&gt;
znana jest pod anglojęzyczną nazwą  ''multitaper''. &lt;br /&gt;
&lt;br /&gt;
Można ją opisać poniższym algorytmem:&lt;br /&gt;
* wygeneruj sekwencję ortogonalnych okienek charakteryzujących się minimalnymi wyciekami widma (stosunek energii w piku centralnym do energii w listkach bocznych jest wysoki). Sekwencja takich okien nazywana jest discrete prolate spheroidal sequences (DPSS) lub sekwencją Slepiana.&lt;br /&gt;
* oblicz widmo sygnału okienkowanego każdym z okien w sekwencji&lt;br /&gt;
* uśrednij otrzymane widma&lt;br /&gt;
&lt;br /&gt;
Kolejne dwa zadania służą zapoznaniu się z tą metodą.&lt;br /&gt;
====Własności okienek DPSS ====&lt;br /&gt;
Do generacji sekwencji okienek DPSS wykorzystamy moduł [http://brain.fuw.edu.pl/edu-wiki/images/f/f6/Gendpss.py Gendpss.py]. Proszę go zapisać w swoim katalogu roboczym. &lt;br /&gt;
Importujemy go do naszych programów tak jak każdy inny moduł np.:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import Gendpss as dpss&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Funkcja potrzebna nam z tego modułu to &amp;lt;tt&amp;gt;gendpss()&amp;lt;/tt&amp;gt;. Funkcja ta wytwarza obiekt reprezentujący konkretną sekwencję DPSS. Wywołujemy ją następująco:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
w = dpss.gendpss(N,NW,K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:gdzie: N: długość okna,&lt;br /&gt;
:        NW: iloczyn czas-szerokość pasma&lt;br /&gt;
:        K: ile okien w sekwencji&lt;br /&gt;
Po powyższym wywołaniu obiekt &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; posiada dwie interesujące nas tablice:&lt;br /&gt;
* &amp;lt;tt&amp;gt;w.lambdas&amp;lt;/tt&amp;gt; - to wartości własne okienek. Są one miarą koncentracji energii w piku głównym, jest to zatem miara jakości okienka (dobre okienka mają wartości własne bliskie 1). Zgodnie z teorią takich wartości powinno być 2*NW-1.&lt;br /&gt;
* &amp;lt;tt&amp;gt;w.dpssarray[i]&amp;lt;/tt&amp;gt; - i-te okienko.&lt;br /&gt;
&lt;br /&gt;
=====Polecenia:=====&lt;br /&gt;
Proszę:&lt;br /&gt;
* wygenerować okienka o długości 256, NW = 2. Ilość okien K raz ustalić na 3 (2*NW-1) a drugi raz na 5. Dla ilu okienek ich wartości własne są bliskie 1?&lt;br /&gt;
* narysować przebieg czasowy okienek&lt;br /&gt;
* sprawdzić czy energia okienek jest znormalizowana do 1.&lt;br /&gt;
* sprawdzić czy kolejne okienka są do siebie ortogonalne. W tym celu należy obliczyć iloczyn skalarny pomiędzy kolejnymi okienkami (np.sum(w.dpssarray[i]*w.dpssarray[j])). &lt;br /&gt;
* wywrysować widma okienek analogicznie jak [[%C4%86wiczenia_3#Badanie_w.C5.82asno.C5.9Bci_okien|w tym ćwiczeniu]]&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import gendpss as dpss&lt;br /&gt;
from numpy.fft import fft,fftshift,fftfreq&lt;br /&gt;
&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1.0/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NW = 2&lt;br /&gt;
ile_okien = 5#2*NW-1&lt;br /&gt;
N_okna = 256&lt;br /&gt;
w = dpss.gendpss(N=N_okna,NW=NW,K=ile_okien)&lt;br /&gt;
print 'Wartości własne:'&lt;br /&gt;
print w.lambdas&lt;br /&gt;
&lt;br /&gt;
print 'Wartości iloczynów skalarnych pomiędzy kolejnymi okienekami:'&lt;br /&gt;
py.figure(1)&lt;br /&gt;
for i in range(ile_okien):&lt;br /&gt;
    py.plot(w.dpssarray[i])&lt;br /&gt;
    for j in range(i+1):&lt;br /&gt;
        print np.sum(w.dpssarray[i]*w.dpssarray[j]),&lt;br /&gt;
    print&lt;br /&gt;
&lt;br /&gt;
py.figure(2)&lt;br /&gt;
NFFT = N_okna*4&lt;br /&gt;
S=np.zeros((ile_okien,NFFT))&lt;br /&gt;
for i in range(ile_okien):&lt;br /&gt;
    py.subplot(ile_okien,1,i+1)&lt;br /&gt;
    (S_db, F)= widmo_dB(w.dpssarray[i], NFFT, 1.0)&lt;br /&gt;
    S[i,:]=S_db&lt;br /&gt;
    py.plot(F,S_db)&lt;br /&gt;
    py.ylim((-200,20))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Estymacja widma mocy metodą multitaper ====&lt;br /&gt;
Proszę napisać funkcję do estymacji mocy metodą multitaper.&lt;br /&gt;
Funkcja powinna pobierać następujące argumenty: sygnał, iloczyn NW, częstość próbkowania sygnału. Funkcja powinna zwracać krotkę &amp;lt;tt&amp;gt;(S,F)&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; widmo mocy, &amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt; skala częstości.&lt;br /&gt;
Przykładowe wywołanie takiej funkcji powinno wyglądać tak:&lt;br /&gt;
&amp;lt;tt&amp;gt; (S,F) = mtm(s,  NW = 3, Fs = 128)&amp;lt;/tt&amp;gt;&lt;br /&gt;
Algorytm do zastosowania wewnątrz funkcji:&lt;br /&gt;
# Oblicz maksymalną liczbę okienek &amp;lt;tt&amp;gt; K = 2*NW-1&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Oblicz długość sygnału&lt;br /&gt;
# wygeneruj serię okienek dpss&lt;br /&gt;
# dla każdego z otrzymanych okienek oblicz widmo mocy iloczynu tego okienka i sygnału. Dla i-tego okienka będzie to: &amp;lt;tt&amp;gt;Si = np.abs(fft(s*w.dpssarray[i]))**2&amp;lt;/tt&amp;gt;&lt;br /&gt;
# uśrednij widma otrzymane dla wszystkich okienek&lt;br /&gt;
# wygeneruj oś częstości (&amp;lt;tt&amp;gt;fftfreq&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Działanie funkcji sprawdź estymując i wykreślając widmo sinusoidy np. o częstości 10 Hz, czasie trwania 1s, próbkowanej 100Hz z dodanym szumem gaussowskim o średniej 0 i wariancji 1. Sprawdź także zachowanie energii przez tą estymatę. Dla porównania na tym samym wykresie dorysuj widmo otrzymane przez [[Nieparametryczne_widmo_mocy#Okienkowanie_a_widmo_mocy:_periodogram|periodogram]] z oknem prostokątnym.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import gendpss as dpss&lt;br /&gt;
from numpy.fft import fft,fftshift,fftfreq&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def mtm(s, NW = 3, Fs = 128):&lt;br /&gt;
    '''estymacja widma w oparciu o  metodę Multiteper &lt;br /&gt;
    D. J. Thomson, “Spectrum Estimation and Harmonic Analysis,” Proceedings of the&lt;br /&gt;
    IEEE, vol. 70, no. 9, pp. 1055 – 1096, 1982.&lt;br /&gt;
    x - sygnał&lt;br /&gt;
    N -ilość punktów okna&lt;br /&gt;
    NW - iloczyn długości okna w czasie i szerokości w częstości&lt;br /&gt;
    K - ilość okien&lt;br /&gt;
&lt;br /&gt;
    funkcja zwraca estymatę mocy widmowej&lt;br /&gt;
    '''&lt;br /&gt;
    K = 2*NW-1&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    w = dpss.gendpss(N,NW,K)&lt;br /&gt;
    S=np.zeros(N)&lt;br /&gt;
    for i in range(K):&lt;br /&gt;
        Si = np.abs(fft(s*w.dpssarray[i]))**2&lt;br /&gt;
        S[:] += Si.real&lt;br /&gt;
    S = S/K&lt;br /&gt;
    F = fftfreq(N,1.0/Fs)&lt;br /&gt;
    return (fftshift(S),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fs = 100.0&lt;br /&gt;
NW = 3&lt;br /&gt;
(s,t) = sin(f=10.2,Fs=Fs)&lt;br /&gt;
s = s+np.random.randn(len(s))&lt;br /&gt;
(S,F) = mtm(s, NW = NW,  Fs = Fs)&lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.plot( F,fftshift(np.abs(fft(s))**2/len(s) ) ,'g')&lt;br /&gt;
&lt;br /&gt;
print np.sum(S)&lt;br /&gt;
print np.sum(s**2)&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=Nieparametryczne_widmo_mocy&amp;diff=4250</id>
		<title>Nieparametryczne widmo mocy</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=Nieparametryczne_widmo_mocy&amp;diff=4250"/>
		<updated>2015-10-05T19:13:29Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Okienkowanie a widmo mocy: periodogram */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Widmo mocy==&lt;br /&gt;
=== Moc===&lt;br /&gt;
Moc chwilowa sygnału przez analogię do układów elektrycznych o jednostkowym oporze jest w analizie sygnałów przyjęta jako kwadraty próbek (&amp;lt;math&amp;gt;P = I^2 R = \frac{U^2}{R}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Oznaczmy sygnał &lt;br /&gt;
&amp;lt;math&amp;gt;x[n]&amp;lt;/math&amp;gt;, wówczas jego moc wyraża się wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;P[n]=x[n]^2&amp;lt;/math&amp;gt;, &lt;br /&gt;
a energia wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;E = \sum _n{x[n]^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
==== Zadanie ====&lt;br /&gt;
Przy pomocy funkcji napisanych na poprzednich zajęciach proszę wygenerować sygnał sinusoidalny o amplitudzie 1, częstości 10 Hz, trwający 0.3 sekundy i próbkowany z częstością 1000 Hz. Proszę narysować ten sygnał przy pomocy funkcji &amp;lt;tt&amp;gt;pylab.stem&amp;lt;/tt&amp;gt;, obliczyć i narysować przebieg mocy w czasie, obliczyć energię tego sygnału.&lt;br /&gt;
&lt;br /&gt;
===Widmo mocy: tw. Plancherela i tw. Parsevala ===&lt;br /&gt;
Twierdzenia te omawiane i dowodzone były na [[Szereg_Fouriera#To.C5.BCsamo.C5.9B.C4.87_Parsevala_dla_szereg.C3.B3w_Fouriera|wykładzie]]. Tutaj, tylko krótko przypomnijmy sobie: &lt;br /&gt;
====Twierdzenie Plancherela====&lt;br /&gt;
Jeśli &amp;lt;math&amp;gt;X[k]&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;Y[k]&amp;lt;/math&amp;gt; są transformatami &amp;lt;math&amp;gt;x[n]&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;y[n]&amp;lt;/math&amp;gt; odpowiednio to:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid15&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\sum _{n=0}^{N-1} x[n]y^*[n] = \frac{1}{N} \sum _{k=0}^{N-1} X[k] Y^*[k]&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
gwiazdka oznacza sorzężenie zespolone. &lt;br /&gt;
====Twierdzenie Parsevala====&lt;br /&gt;
jest specjalnym przypadkiem twierdzenia Plancherela:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid16&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\sum _{n=0}^{N-1} \left|x[n]\right|^2 = \frac{1}{N} \sum _{k=0}^{N-1} \left|X[k]\right|^2.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
Twierdzenie to upoważnia nas do utożsamiania kwadratów wartości bezwzględnej składowych transformaty Fouriera z mocą niesioną przez odpowiadające im składowe.&lt;br /&gt;
&lt;br /&gt;
=== Zadanie: funkcja do estymacji widma mocy ===&lt;br /&gt;
Proszę napisać i przetestować funkcję realizującą następujący algorytm estymacji widma mocy:&lt;br /&gt;
# Jako parametry funkcja przyjmuje sygnał &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; i częstość próbkowania tego sygnału&lt;br /&gt;
# Oblicz transformatę Fouriera sygnału przy pomocy &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Unormuj otrzymaną transformatę przez pierwiastek z ilości próbek sygnału&lt;br /&gt;
# Oblicz moc jako iloczyn unormowanej transformaty i jej sprzężenia zespolonego. W pythonie sprzężenie zespolone liczby &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; otrzymujemy korzystając z metody &amp;lt;tt&amp;gt;S.conj()&amp;lt;/tt&amp;gt;. W wyniku powyższego iloczynu dostaniemy liczby zespolone o zerowej części urojonej (proszę to sprawdzić). &lt;br /&gt;
# Do dalszych operacji wybierz tylko część rzeczywistą mocy. Część rzeczywistą liczby zespolonej M pobieramy w następujący sposób: &amp;lt;tt&amp;gt;czesc_rzeczywista_M = M.real&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Korzystając z funkcji &amp;lt;tt&amp;gt;fftfreq&amp;lt;/tt&amp;gt; obliczamy częstości, dla których policzone są współczynniki Fouriera.&lt;br /&gt;
# Przy pomocy funkcji &amp;lt;tt&amp;gt;fftshift&amp;lt;/tt&amp;gt; porządkujemy kolejność wektorów mocy i częstości, tak aby częstości były reprezentowane od -częstości Nyquista, przez 0, do +częstości Nyquista&lt;br /&gt;
# zwracamy uporządkowane wektory mocy i częstości&lt;br /&gt;
&lt;br /&gt;
Testowanie:&lt;br /&gt;
&lt;br /&gt;
# przy pomocy funkcji sin napisanej na drugich ćwiczeniach  wygeneruj sinusoidę o długości 1 s, o częstości 10Hz, próbkowaną 100 Hz.&lt;br /&gt;
# oblicz moc w czasie (trzeba podnieść wartość każdej próbki do kwadratu)&lt;br /&gt;
# oblicz moc w częstości przy pomocy funkcji estymacji widma mocy&lt;br /&gt;
# oblicz energię sygnału w czasie&lt;br /&gt;
# oblicz energię sygnału w częstości&lt;br /&gt;
# wykreśl: &lt;br /&gt;
#* sygnał&lt;br /&gt;
#* przebieg jego mocy w czasie&lt;br /&gt;
#* przebieg mocy w częstości&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import rfft,fft,fftfreq,fftshift&lt;br /&gt;
 &lt;br /&gt;
def widmo_mocy(s, Fs):&lt;br /&gt;
    S = fft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = S*S.conj()&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (fftshift(S_moc),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
(s,t) = sin(f=10,Fs=100.0)&lt;br /&gt;
moc_w_czasie = s**2&lt;br /&gt;
(moc_w_czestosci, F) = widmo_mocy(s, Fs=100.0)&lt;br /&gt;
&lt;br /&gt;
energia_w_czasie = np.sum(moc_w_czasie)&lt;br /&gt;
energia_w_czestosci = np.sum(moc_w_czestosci)&lt;br /&gt;
print 'energia w czasie: ', energia_w_czasie&lt;br /&gt;
print 'energia w czestosci: ', energia_w_czestosci&lt;br /&gt;
&lt;br /&gt;
py.subplot(3,1,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title('Sygnał')&lt;br /&gt;
py.subplot(3,1,2)&lt;br /&gt;
py.plot(t,moc_w_czasie)&lt;br /&gt;
py.title('moc w czasie')&lt;br /&gt;
py.subplot(3,1,3)&lt;br /&gt;
py.plot(F,moc_w_czestosci)&lt;br /&gt;
py.title('moc w częstości')&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===Rozdzielczość widma===&lt;br /&gt;
Proszę zbadać rozdzielczość częstotliwościową widma w zależności od długości sygnału. Używamy funkcji &amp;lt;tt&amp;gt;m_sin&amp;lt;/tt&amp;gt;. Zwrócić uwagę na to co dzieje się na końcach odcinka.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Okienkowanie a widmo mocy: periodogram===&lt;br /&gt;
Przypomnijmy wzór na dyskretną transformatę Fouriera [http://haar.zfb.fuw.edu.pl/edu/index.php/%C4%86wiczenia_2 DFT] zaimplementowaną w FFT: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;S[k] =  \sum_{n=0}^{n-1} s[n] \exp\left\{-2\pi i{nk \over N}\right\}       \qquad k = 0,\ldots,N-1.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Na podstawie twierdzenia [[Nieparametryczne_widmo_mocy#Twierdzenie_Parsevala|Parsevala]] możemy policzyć widmo mocy jako:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P[k] = \frac{1}{N}  \left|S[k]\right|^2 &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeśli do liczenia mocy chcielibyśmy posłużyć się techniką okiennkowania sygnału, to powinniśmy używać okienek znormalizowanych, czyli takich których energia jest równa 1, wtedy mnożenie przez okienko nie zaburzy estymaty energii sygnału. &lt;br /&gt;
&lt;br /&gt;
Aby policzyć widmo mocy sygnału z zastosowaniem okienek wprowadzimy następujące symbole:&lt;br /&gt;
* sygnał: &amp;lt;math&amp;gt;s[n]&amp;lt;/math&amp;gt;&lt;br /&gt;
* okienko: &amp;lt;math&amp;gt; w[n]&amp;lt;/math&amp;gt;&lt;br /&gt;
* okienko znormalizowane: &amp;lt;math&amp;gt; \hat w[n] = \frac{1}{\sqrt{\sum_{n=0}^{N-1} (w[n])^2}}w[n]&amp;lt;/math&amp;gt; &lt;br /&gt;
&amp;lt;!--(w szczególnym przypadku okienka prostokątnego normalizacja ta daje &amp;lt;math&amp;gt;1/N^2&amp;lt;/math&amp;gt; występujące we wzorze na moc)--&amp;gt;&lt;br /&gt;
* widmo mocy sygnału okienkowanego:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P[k] = \frac{1}{\sum_{n=0}^{N-1} (w[n])^2}  \left|\sum_{n=0}^{N-1} s[n]w[n] e^{i\frac{2 \pi }{N} k n}\right|^2 &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Zadanie ====&lt;br /&gt;
Proszę napisać funkcję obliczającą periodogram.&lt;br /&gt;
Funkcja jako argumenty powinna przyjmować sygnał, okno (podane jako sekwencja próbek), i częstość próbkowania. Zwracać powinna widmo mocy i skalę osi częstości. Wewnątrz funkcja powinna implementować liczenie widma z sygnału okienkowanego znormalizowanym oknem.&lt;br /&gt;
&lt;br /&gt;
Funkcję proszę przetestować obliczając dla funkcji sinus energię sygnału w dziedzinie czasu i w dziedzinie częstości. Testy proszę wykonać dla okna prostokątnego, Blackmana i Haminga.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , F_samp):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    F_samp- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 10.1, T =2, Fs = F_samp, phi = 0)&lt;br /&gt;
N = len(x) # dłogość sygnału&lt;br /&gt;
okno = np.ones(N)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N)&lt;br /&gt;
#okno = np.hamming(N)&lt;br /&gt;
&lt;br /&gt;
s = x*okno # sygnał okienkowany&lt;br /&gt;
#&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,x)&lt;br /&gt;
energia_t = np.sum(x**2)&lt;br /&gt;
print 'energia sygnału:', energia_t&lt;br /&gt;
py.title(u' sygnał')&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał')&lt;br /&gt;
py.title(u' sygnał okienkowany ')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
(S,F) = widmo_dB(s,N,F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego')&lt;br /&gt;
py.ylabel('dB')&lt;br /&gt;
&lt;br /&gt;
#periodogram&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
(P, F) = periodogram(x,okno,F_samp)&lt;br /&gt;
py.plot(F,P)&lt;br /&gt;
        &lt;br /&gt;
py.title('periodogram')&lt;br /&gt;
print 'energia periodogramu:', np.sum(P)&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Sygnały stochastyczne ==&lt;br /&gt;
Sygnał stochastyczny to taki sygnał, dla którego ciągu próbek nie da się opisać funkcją czasu. Kolejne próbki w takim sygnale to [[Zmienne_losowe_i_generatory_liczb_pseudolosowych#Zmienna_losowa|zmienne losowe]]. Można je opisać podając własności [[Zmienne_losowe_i_generatory_liczb_pseudolosowych#Rozk.C5.82ad_prawdopodobie.C5.84stwa|rozkładu]], z k†órego pochodzą. Często w opisie takich zmiennych posługujemy się [[WnioskowanieStatystyczne/Zmienne_losowe_i_generatory_liczb_pseudolosowych#Momenty|momentami rozkładów]].&lt;br /&gt;
Jak można sobie wyobrazić rozkłady, z których pochodzą próbki?&lt;br /&gt;
Można sobie wyobrazić,że obserwowany przez nas sygnał stochastyczny to jedna z możliwych realizacji procesu stochastycznego. &lt;br /&gt;
Jeśli &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; jest zbiorem &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; zdarzeń (&amp;lt;math&amp;gt;k \in K&amp;lt;/math&amp;gt;) i każde z tych zdarzeń ma przypisaną funkcję &amp;lt;math&amp;gt;x_k(t)&amp;lt;/math&amp;gt; zwaną realizacją procesu &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt;, to proces stochastyczny może być zdefiniowany jako zbiór funkcji:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid23&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\xi (t) = \left\lbrace x_1(t),x_2(t),\dots , x_N(t) \right\rbrace &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;x_k(t)&amp;lt;/math&amp;gt; są losowymi funkcjami czasu &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Procesy stochastyczne można opisywać prze wartości oczekiwane liczone po realizacjach.&lt;br /&gt;
&lt;br /&gt;
Dla przypomnienia wartość oczekiwaną liczymy tak:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid24&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
{\mu _x(t_1) = E\left[\xi (t_1) \right]= \lim _{N \rightarrow \infty }\sum _{k=1}^{N}{x_k(t_1)} p(x_k,t_1)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
średnia &amp;lt;math&amp;gt;\mu _x(t_1)&amp;lt;/math&amp;gt; procesu &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt; w chwili &amp;lt;math&amp;gt;t_1&amp;lt;/math&amp;gt; to suma wartośći zaobserwowanych w chwili we wszystkich realizacjach &amp;lt;math&amp;gt;t_1&amp;lt;/math&amp;gt; ważona prawdopodobieństwem wystąpienia tej realizacji:&lt;br /&gt;
=== Stacjonarność i ergodyczność===&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
	&amp;lt;dt&amp;gt;&lt;br /&gt;
	Stacjonarność:&lt;br /&gt;
	&amp;lt;dd&amp;gt;&lt;br /&gt;
	Jeśli dla procesu stochastycznego &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt; wszystkie momenty są niezależne od czasu to jest on stajonarny w ścisłym sensie. Jeśli tylko średnia &amp;lt;math&amp;gt;\mu _x&amp;lt;/math&amp;gt; i autokorelacja &amp;lt;math&amp;gt;R_x(\tau )&amp;lt;/math&amp;gt; nie zależą od czasu to proces jest stacjonarny w słabym sensie, co dla wielu zastosowań jest wystarczające.&lt;br /&gt;
	&amp;lt;dt&amp;gt;&lt;br /&gt;
	Ergodyczność:&lt;br /&gt;
	&amp;lt;dd&amp;gt;&lt;br /&gt;
	Proces jest ergodyczny jeśli jego średnie po czasie i po realizacjach są sobie równe. Oznacza to, że dla takiego procesu jedna realizacja jest reprezentatywna i zawiera całą informację o tym procesie.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Założenie o sygnale, że jest stacjonarny i ergodyczny pozwala zamienić sumowanie po realizacjach na sumowanie po czasie w estymatory momentów statystycznych.&lt;br /&gt;
&lt;br /&gt;
===Transformata Fouriera sygnału stochastycznego===&lt;br /&gt;
Bardzo często musimy oszacować widmo mocy sygnału zawierającego znaczny udział szumu.&lt;br /&gt;
&lt;br /&gt;
Poniższe ćwiczenie ilustruje niepewność szacowania pików w widmie otrzymanym z transformaty Fouriera dla sygnału zawierającego szum.&lt;br /&gt;
&lt;br /&gt;
* wygeneruj 20 realizacji sygnału będącego sumą sinusoidy (f=20Hz, T=1s, Fs =100Hz) i  szumu gaussowskiego&lt;br /&gt;
* dla każdej realizacji oblicz widmo mocy&lt;br /&gt;
* wykreśl wszystkie otrzymane widma na wspólnym wykresie&lt;br /&gt;
&lt;br /&gt;
Proszę obejrzeć otrzymane widma.&lt;br /&gt;
* Zaobserwuj jakiego rzędu jest niepewność wyniku.&lt;br /&gt;
* Czy podobny problem występuje dla sygnału bez szumu?&lt;br /&gt;
* Skonstruuj funkcję rysującą średnie widmo wraz z [[Przedzia%C5%82y_ufno%C5%9Bci#Zadanie_2 95%|przedziałem ufności]].&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import scipy.stats as st&lt;br /&gt;
&lt;br /&gt;
from numpy.fft import rfft,fft,fftfreq,fftshift&lt;br /&gt;
 &lt;br /&gt;
def widmo_mocy(s, Fs):&lt;br /&gt;
    '''funkcja oblicza widmo mocy sygnału i oś częstości&lt;br /&gt;
    s - sygnał&lt;br /&gt;
    Fs - częstość próbkowania&lt;br /&gt;
    '''&lt;br /&gt;
    S = fft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = S*S.conj()&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (fftshift(S_moc),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def widmo_mocy_rzeczywistego(s,FS):&lt;br /&gt;
    '''funkcja oblicza widmo mocy sygnału rzeczywistego i oś częstości&lt;br /&gt;
    s - sygnał&lt;br /&gt;
    Fs - częstość próbkowania&lt;br /&gt;
&lt;br /&gt;
    zwraca dodatnią część widma&lt;br /&gt;
    '''&lt;br /&gt;
    S = rfft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = np.abs(S)**2&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (S_moc,F)&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def szum(mu =0 , sigma = 1, T = 1, Fs = 128):&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.random.randn(len(t) )*sigma + mu&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def dwadziescia_realizacji(FS):&lt;br /&gt;
    '''&lt;br /&gt;
    *  wygeneruj 20 realizacji sygnału będącego sumą sinusoidy (f=20Hz, T=1s, Fs =100Hz) i szumu gassowskiego&lt;br /&gt;
    * dla każdej realizacji oblicz widmo mocy&lt;br /&gt;
    * wykreśl wszystkie otrzymane widma na wspólnym wykresie &lt;br /&gt;
    '''&lt;br /&gt;
    for i in range(20):&lt;br /&gt;
        (s,t) = sin(f=10,Fs=FS)&lt;br /&gt;
        (sz,t) = szum(Fs =FS)&lt;br /&gt;
        syg = s + sz&lt;br /&gt;
        (moc_w_czestosci, F) = widmo_mocy(syg, Fs=FS)&lt;br /&gt;
        py.plot(F,moc_w_czestosci)&lt;br /&gt;
    py.show()&lt;br /&gt;
    &lt;br /&gt;
def srednie_widmo(FS):&lt;br /&gt;
    '''&lt;br /&gt;
    #  Skonstruuj funkcję rysującą średnie widmo wraz z 95% przedziałem ufności. &lt;br /&gt;
    '''&lt;br /&gt;
    zbior_widm = np.zeros((20,FS))&lt;br /&gt;
    for i in range(20):&lt;br /&gt;
        (s,t) = sin(f=10,Fs=FS)&lt;br /&gt;
        (sz,t) = szum(Fs =FS)&lt;br /&gt;
        syg = s + sz&lt;br /&gt;
        (moc_w_czestosci, F) = widmo_mocy(syg, Fs=FS)&lt;br /&gt;
        zbior_widm[i][:] = moc_w_czestosci&lt;br /&gt;
    srednie_w = np.mean(zbior_widm,axis =0)&lt;br /&gt;
    przedzial_d = np.zeros(len(F))&lt;br /&gt;
    przedzial_g = np.zeros(len(F))&lt;br /&gt;
    for f in F:&lt;br /&gt;
        przedzial_d[f] = st.scoreatpercentile(zbior_widm[:,f], 2.5)&lt;br /&gt;
        przedzial_g[f] = st.scoreatpercentile(zbior_widm[:,f], 97.5)&lt;br /&gt;
    py.plot(F,srednie_w,'r')&lt;br /&gt;
    py.plot(F,przedzial_d,'b')&lt;br /&gt;
    py.plot(F,przedzial_g,'b')&lt;br /&gt;
    py.show()&lt;br /&gt;
&lt;br /&gt;
FS =100.0    &lt;br /&gt;
#dwadziescia_realizacji(FS)&lt;br /&gt;
srednie_widmo(FS)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Oszacowanie błędu transformaty Fouriera dla białego szumu ===&lt;br /&gt;
Dla sygnału stochastycznego &amp;lt;math&amp;gt;x(t)&amp;lt;/math&amp;gt;, którego kolejne próbki pochodzą z niezależnych rozkładów normalnych (biały szum), jego transformata Fouriera &amp;lt;math&amp;gt;X(f)&amp;lt;/math&amp;gt; jest liczbą zespoloną, której część rzeczywista &amp;lt;math&amp;gt;X_R(f)&amp;lt;/math&amp;gt; i urojona &amp;lt;math&amp;gt;X_I(f)&amp;lt;/math&amp;gt; mogą być uznane za nieskorelowane zmienne losowe o średniej zero i równych wariancjach. Ponieważ transformata Fouriera jest operacją liniową więc składowe  &amp;lt;math&amp;gt;X_R(f)&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;X_I(f)&amp;lt;/math&amp;gt; mają rozkłady normalne. Zatem wielkość:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P(f) = |X(f)|^2 = X_R^2(f) + X_I^2(f)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
jest sumą kwadratów dwóch niezależnych zmiennych normalnych. Wielkość ta podlega zatem rozkładowi &amp;lt;math&amp;gt;\chi^2&amp;lt;/math&amp;gt; o dwóch stopniach swobody.&lt;br /&gt;
Możemy oszacować względny błąd &amp;lt;math&amp;gt;P(f_1) &amp;lt;/math&amp;gt; dla danej częstości &amp;lt;math&amp;gt;f_1&amp;lt;/math&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\epsilon_r= \sigma_{P_{f_1}}/\mu_{P_{f_1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dla rozkładu &amp;lt;math&amp;gt;\chi_2^2&amp;lt;/math&amp;gt;:  &amp;lt;math&amp;gt;\sigma^2 = 2n&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;\mu = n&amp;lt;/math&amp;gt;, gdzie &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; jest ilością stopni swobody. W naszym przypadku &amp;lt;math&amp;gt;n =2&amp;lt;/math&amp;gt; więc mamy &amp;lt;math&amp;gt;\epsilon_f = 1&amp;lt;/math&amp;gt;, co oznacza, że dla pojedynczego binu częstości w widmie &amp;lt;math&amp;gt;P(f)&amp;lt;/math&amp;gt; względny błąd wynosi 100%. &lt;br /&gt;
&lt;br /&gt;
Aby zmniejszyć ten błąd trzeba zwiększyć ilość stopni swobody. Są generalnie stosowane dwie techniki. Pierwsza to uśrednianie sąsiednich binów częstości. Otrzymujemy wówczas wygładzony estymator mocy &amp;lt;math&amp;gt;\hat{P}_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\hat{P}_k = \frac{1}{l}[P_k + P_{k+1} + \dots + P_{k+l-1}]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zakładając, że biny częstości  &amp;lt;math&amp;gt;P_i&amp;lt;/math&amp;gt; są niezależne estymator &amp;lt;math&amp;gt;P_k&amp;lt;/math&amp;gt; ma rozkład &amp;lt;math&amp;gt;\chi^2&amp;lt;/math&amp;gt; o ilości stopni swobody równej &amp;lt;math&amp;gt;n= 2l&amp;lt;/math&amp;gt;. Względny błąd takiego estymatora to: &amp;lt;math&amp;gt;\epsilon_r= \sqrt{\frac{1}{l}}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Innym sposobem poprawy estymatora mocy jest podzielenie sygnału na fragmenty, obliczenie periodogramu dla każdego fragmentu, a następnie zsumowanie otrzymanych wartości:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\hat{P}_k=[P_{k,1}+P_{k,2}+\dots+P_{k,j}+\dots+P_{k,q}]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;S_{k,j}&amp;lt;/math&amp;gt; jest estymatą składowej o częstości &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; w oparciu o &amp;lt;math&amp;gt;j-ty&amp;lt;/math&amp;gt; fragment sygnału. Ilość stopni swobody wynosi w tym przypadku &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; zatem względny błąd wynosi: &amp;lt;math&amp;gt;\epsilon_r = \sqrt{\frac{1}{q}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Zauważmy, że w obu metodach zmniejszamy wariancję estymatora kosztem rozdzielczości w częstości.&lt;br /&gt;
&lt;br /&gt;
===Metoda Welcha===&lt;br /&gt;
Proszę napisać i przetestować funkcję implementującą metodę Welcha estymacji widma mocy. Algorytm Welcha:&lt;br /&gt;
# sygnał &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; o długości ''N'' jest dzielony na segmenty, każdy o długości &amp;lt;math&amp;gt;N_s&amp;lt;/math&amp;gt;. Odcinki mogą na siebie zachodzić na &amp;lt;math&amp;gt;N_z&amp;lt;/math&amp;gt; punktów. Czyli są względem siebie przesunięte o &amp;lt;math&amp;gt;N_p = N_s-N_z&amp;lt;/math&amp;gt;.&lt;br /&gt;
# z każdego segmentu liczony jest okienkowany periodogram&lt;br /&gt;
# periodogramy są sumowane&lt;br /&gt;
# wynik dzielony jest przez efektywne wykorzystanie każdego kawałka sygnału w estymacie: &amp;lt;tt&amp;gt;K_eff = dlogosc_okna * ilosc_okien / dlugosc_sygnalu&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funkcję proszę przetestować obliczając dla funkcji sinus energię sygnału w dziedzinie czasu i w dziedzinie częstości. Testy proszę wykonać dla okna prostokątnego, Blackmana i Haminga. &lt;br /&gt;
&lt;br /&gt;
 * &amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
def pwelch(s,okienko, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okienko)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,F_samp)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Całość razem z kodem testującym:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , Fs):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    Fs- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
def pwelch(s,okienko, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okienko)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,Fs)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 3.1, T =20, Fs = F_samp, phi = 0)&lt;br /&gt;
N = len(x) # dłogość sygnału&lt;br /&gt;
&lt;br /&gt;
okno = np.ones(N)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N)&lt;br /&gt;
#okno = np.hamming(N)&lt;br /&gt;
&lt;br /&gt;
s = x*okno # sygnał okienkowany&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
(P, F) = periodogram(x,okno,F_samp)&lt;br /&gt;
py.plot(F,P) &lt;br /&gt;
py.title('periodogram'+' energia: '+ str(np.sum(P)))&lt;br /&gt;
&lt;br /&gt;
#periodogram&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
N_s = N/8&lt;br /&gt;
#okno = np.ones(N_s)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N_s)&lt;br /&gt;
okno = np.hamming(N_s)&lt;br /&gt;
&lt;br /&gt;
         &lt;br /&gt;
(P, F) = pwelch(x,okno,N_s/10,F_samp)&lt;br /&gt;
py.plot(F,P)&lt;br /&gt;
py.title('periodogram Welcha'+' energia: '+ str(np.sum(P)))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Porównanie rozdzielczości i wariancji w periodogramie i w estymatorze Welcha===&lt;br /&gt;
#  wygeneruj 100 realizacji sygnału będącego sumą sinusoidy (f=20Hz, T=10s, Fs =100Hz) i szumu gaussowskiego&lt;br /&gt;
# dla każdej realizacji oblicz widmo mocy za pomocą periodogramu okienkowanego oknem Blackmana&lt;br /&gt;
# wykreśl wszystkie otrzymane widma na wspólnym wykresie (subplot(2,1,1))&lt;br /&gt;
# Powtórz krok 2) dla estymatora Welcha z oknem Blackmana o długości 1/10 długości sygnału przesuwanym co 2 punkty, otrzymane widma wykreśl  na wspólnym wykresie (subplot(2,1,2))&lt;br /&gt;
&lt;br /&gt;
* Co można powiedzieć o rozdzielczości i względnym błędzie obu metod?&lt;br /&gt;
&amp;lt;tt&amp;gt;bl_wzg = np.std(S,axis = 0)/np.mean(S,axis = 0)&amp;lt;/tt&amp;gt; gdzie S jest tablicą zawierającą widma dla każdej z realizacji.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , Fs):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    Fs- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/Fs)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
def pwelch(s,okno, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okno)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,Fs)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&lt;br /&gt;
def realizacja(T,Fs):&lt;br /&gt;
    (x,t) = sin(f = 20.0, T = T, Fs = Fs, phi = 0)&lt;br /&gt;
    x += 2*np.random.randn(len(x))&lt;br /&gt;
    return x&lt;br /&gt;
&lt;br /&gt;
T=10.0&lt;br /&gt;
Fs = 100.0&lt;br /&gt;
N = T*Fs&lt;br /&gt;
Nw = N/10.0&lt;br /&gt;
okno = np.blackman(N)&lt;br /&gt;
okno_welch = np.blackman(Nw)&lt;br /&gt;
&lt;br /&gt;
N_rep = 100&lt;br /&gt;
S_perio = np.zeros((N_rep,N))&lt;br /&gt;
S_welch = np.zeros((N_rep,Nw))&lt;br /&gt;
py.figure(1)&lt;br /&gt;
for i in range(N_rep):&lt;br /&gt;
    s = realizacja(T,Fs)&lt;br /&gt;
    (P, F) = periodogram(s,okno,Fs) &lt;br /&gt;
    S_perio[i] = P&lt;br /&gt;
    py.subplot(2,1,1)&lt;br /&gt;
    py.plot(F,P) &lt;br /&gt;
    (P, F) = pwelch(s,okno_welch,Nw/10,Fs)&lt;br /&gt;
    S_welch[i] = P&lt;br /&gt;
    py.subplot(2,1,2)&lt;br /&gt;
    py.plot(F,P)&lt;br /&gt;
&lt;br /&gt;
py.figure(2)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(np.std(S_perio,axis = 0)/np.mean(S_perio,axis = 0))&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.std(S_welch,axis = 0)/np.mean(S_welch,axis = 0))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Wielookienkowa metoda Thomsona===&lt;br /&gt;
Metoda ta &lt;br /&gt;
[http://ieeexplore.ieee.org/Xplore/login.jsp?url=http%3A%2F%2Fieeexplore.ieee.org%2Fiel5%2F5%2F31317%2F01456701.pdf%3Farnumber%3D1456701&amp;amp;authDecision=-201 Spectrum estimation and harmonic analysis] &lt;br /&gt;
znana jest pod anglojęzyczną nazwą  ''multitaper''. &lt;br /&gt;
&lt;br /&gt;
Można ją opisać poniższym algorytmem:&lt;br /&gt;
* wygeneruj sekwencję ortogonalnych okienek charakteryzujących się minimalnymi wyciekami widma (stosunek energii w piku centralnym do energii w listkach bocznych jest wysoki). Sekwencja takich okien nazywana jest discrete prolate spheroidal sequences (DPSS) lub sekwencją Slepiana.&lt;br /&gt;
* oblicz widmo sygnału okienkowanego każdym z okien w sekwencji&lt;br /&gt;
* uśrednij otrzymane widma&lt;br /&gt;
&lt;br /&gt;
Kolejne dwa zadania służą zapoznaniu się z tą metodą.&lt;br /&gt;
====Własności okienek DPSS ====&lt;br /&gt;
Do generacji sekwencji okienek DPSS wykorzystamy moduł [http://brain.fuw.edu.pl/edu-wiki/images/f/f6/Gendpss.py Gendpss.py]. Proszę go zapisać w swoim katalogu roboczym. &lt;br /&gt;
Importujemy go do naszych programów tak jak każdy inny moduł np.:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import Gendpss as dpss&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Funkcja potrzebna nam z tego modułu to &amp;lt;tt&amp;gt;gendpss()&amp;lt;/tt&amp;gt;. Funkcja ta wytwarza obiekt reprezentujący konkretną sekwencję DPSS. Wywołujemy ją następująco:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
w = dpss.gendpss(N,NW,K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:gdzie: N: długość okna,&lt;br /&gt;
:        NW: iloczyn czas-szerokość pasma&lt;br /&gt;
:        K: ile okien w sekwencji&lt;br /&gt;
Po powyższym wywołaniu obiekt &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; posiada dwie interesujące nas tablice:&lt;br /&gt;
* &amp;lt;tt&amp;gt;w.lambdas&amp;lt;/tt&amp;gt; - to wartości własne okienek. Są one miarą koncentracji energii w piku głównym, jest to zatem miara jakości okienka (dobre okienka mają wartości własne bliskie 1). Zgodnie z teorią takich wartości powinno być 2*NW-1.&lt;br /&gt;
* &amp;lt;tt&amp;gt;w.dpssarray[i]&amp;lt;/tt&amp;gt; - i-te okienko.&lt;br /&gt;
&lt;br /&gt;
=====Polecenia:=====&lt;br /&gt;
Proszę:&lt;br /&gt;
* wygenerować okienka o długości 256, NW = 2. Ilość okien K raz ustalić na 3 (2*NW-1) a drugi raz na 5. Dla ilu okienek ich wartości własne są bliskie 1?&lt;br /&gt;
* narysować przebieg czasowy okienek&lt;br /&gt;
* sprawdzić czy energia okienek jest znormalizowana do 1.&lt;br /&gt;
* sprawdzić czy kolejne okienka są do siebie ortogonalne. W tym celu należy obliczyć iloczyn skalarny pomiędzy kolejnymi okienkami (np.sum(w.dpssarray[i]*w.dpssarray[j])). &lt;br /&gt;
* wywrysować widma okienek analogicznie jak [[%C4%86wiczenia_3#Badanie_w.C5.82asno.C5.9Bci_okien|w tym ćwiczeniu]]&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import gendpss as dpss&lt;br /&gt;
from numpy.fft import fft,fftshift,fftfreq&lt;br /&gt;
&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1.0/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NW = 2&lt;br /&gt;
ile_okien = 5#2*NW-1&lt;br /&gt;
N_okna = 256&lt;br /&gt;
w = dpss.gendpss(N=N_okna,NW=NW,K=ile_okien)&lt;br /&gt;
print 'Wartości własne:'&lt;br /&gt;
print w.lambdas&lt;br /&gt;
&lt;br /&gt;
print 'Wartości iloczynów skalarnych pomiędzy kolejnymi okienekami:'&lt;br /&gt;
py.figure(1)&lt;br /&gt;
for i in range(ile_okien):&lt;br /&gt;
    py.plot(w.dpssarray[i])&lt;br /&gt;
    for j in range(i+1):&lt;br /&gt;
        print np.sum(w.dpssarray[i]*w.dpssarray[j]),&lt;br /&gt;
    print&lt;br /&gt;
&lt;br /&gt;
py.figure(2)&lt;br /&gt;
NFFT = N_okna*4&lt;br /&gt;
S=np.zeros((ile_okien,NFFT))&lt;br /&gt;
for i in range(ile_okien):&lt;br /&gt;
    py.subplot(ile_okien,1,i+1)&lt;br /&gt;
    (S_db, F)= widmo_dB(w.dpssarray[i], NFFT, 1.0)&lt;br /&gt;
    S[i,:]=S_db&lt;br /&gt;
    py.plot(F,S_db)&lt;br /&gt;
    py.ylim((-200,20))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Estymacja widma mocy metodą multitaper ====&lt;br /&gt;
Proszę napisać funkcję do estymacji mocy metodą multitaper.&lt;br /&gt;
Funkcja powinna pobierać następujące argumenty: sygnał, iloczyn NW, częstość próbkowania sygnału. Funkcja powinna zwracać krotkę &amp;lt;tt&amp;gt;(S,F)&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; widmo mocy, &amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt; skala częstości.&lt;br /&gt;
Przykładowe wywołanie takiej funkcji powinno wyglądać tak:&lt;br /&gt;
&amp;lt;tt&amp;gt; (S,F) = mtm(s,  NW = 3, Fs = 128)&amp;lt;/tt&amp;gt;&lt;br /&gt;
Algorytm do zastosowania wewnątrz funkcji:&lt;br /&gt;
# Oblicz maksymalną liczbę okienek &amp;lt;tt&amp;gt; K = 2*NW-1&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Oblicz długość sygnału&lt;br /&gt;
# wygeneruj serię okienek dpss&lt;br /&gt;
# dla każdego z otrzymanych okienek oblicz widmo mocy iloczynu tego okienka i sygnału. Dla i-tego okienka będzie to: &amp;lt;tt&amp;gt;Si = np.abs(fft(s*w.dpssarray[i]))**2&amp;lt;/tt&amp;gt;&lt;br /&gt;
# uśrednij widma otrzymane dla wszystkich okienek&lt;br /&gt;
# wygeneruj oś częstości (&amp;lt;tt&amp;gt;fftfreq&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Działanie funkcji sprawdź estymując i wykreślając widmo sinusoidy np. o częstości 10 Hz, czasie trwania 1s, próbkowanej 100Hz z dodanym szumem gaussowskim o średniej 0 i wariancji 1. Sprawdź także zachowanie energii przez tą estymatę. Dla porównania na tym samym wykresie dorysuj widmo otrzymane przez [[Nieparametryczne_widmo_mocy#Okienkowanie_a_widmo_mocy:_periodogram|periodogram]] z oknem prostokątnym.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import gendpss as dpss&lt;br /&gt;
from numpy.fft import fft,fftshift,fftfreq&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def mtm(s, NW = 3, Fs = 128):&lt;br /&gt;
    '''estymacja widma w oparciu o  metodę Multiteper &lt;br /&gt;
    D. J. Thomson, “Spectrum Estimation and Harmonic Analysis,” Proceedings of the&lt;br /&gt;
    IEEE, vol. 70, no. 9, pp. 1055 – 1096, 1982.&lt;br /&gt;
    x - sygnał&lt;br /&gt;
    N -ilość punktów okna&lt;br /&gt;
    NW - iloczyn długości okna w czasie i szerokości w częstości&lt;br /&gt;
    K - ilość okien&lt;br /&gt;
&lt;br /&gt;
    funkcja zwraca estymatę mocy widmowej&lt;br /&gt;
    '''&lt;br /&gt;
    K = 2*NW-1&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    w = dpss.gendpss(N,NW,K)&lt;br /&gt;
    S=np.zeros(N)&lt;br /&gt;
    for i in range(K):&lt;br /&gt;
        Si = np.abs(fft(s*w.dpssarray[i]))**2&lt;br /&gt;
        S[:] += Si.real&lt;br /&gt;
    S = S/K&lt;br /&gt;
    F = fftfreq(N,1.0/Fs)&lt;br /&gt;
    return (fftshift(S),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fs = 100.0&lt;br /&gt;
NW = 3&lt;br /&gt;
(s,t) = sin(f=10.2,Fs=Fs)&lt;br /&gt;
s = s+np.random.randn(len(s))&lt;br /&gt;
(S,F) = mtm(s, NW = NW,  Fs = Fs)&lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.plot( F,fftshift(np.abs(fft(s))**2/len(s) ) ,'g')&lt;br /&gt;
&lt;br /&gt;
print np.sum(S)&lt;br /&gt;
print np.sum(s**2)&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4249</id>
		<title>Ćwiczenia 2 2</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4249"/>
		<updated>2015-10-05T19:04:16Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Rekonstrukcja sygnału ze współczynników */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Zadania ===&lt;br /&gt;
&lt;br /&gt;
==== Współczynniki obliczane przez FFT ====&lt;br /&gt;
Najprostsza sytuacja: Badamy współczynniki zwracane przez &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt; dla sinusoid o różnych częstościach. Wykorzystujemy funkcje do generacji sygnałów napisane na poprzednich zajęciach.&lt;br /&gt;
&lt;br /&gt;
* Proszę kolejno wygenerować sinusoidy o długości 1s próbkowaną 128Hz i częstościach 1,10,30, 64  i  0 Hz. Dla tych sinusoid proszę policzyć transformaty Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wyglądają otrzymane wykresy?&lt;br /&gt;
** Czy coś szczególnego dzieje się dla częstości 0 i 64Hz? Czy w tych skrajnych przypadkach faza sygnału ma wpływ na wynik transformaty? &lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał delta położony w sekundzie 0,5 na odcinku czasu o długości 1s próbkowany 128Hz. Dla takiego sygnału proszę policzyć transformatę Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wygląda transformata funkcji delta? Jakie częstości w sobie zawiera?&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
# skrypt implemetujący polecenia w sekcji&lt;br /&gt;
# Współczynniki obliczane przez FFT&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
def delta(t0=0.5, T=1  ,Fs = 128):&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	d = np.zeros(len(t))&lt;br /&gt;
	d[np.ceil(t0*Fs)]=1&lt;br /&gt;
	return (d,t)&lt;br /&gt;
 &lt;br /&gt;
# do pytania 1&lt;br /&gt;
(s,t) = sin(f=2,T=1,Fs=10,phi=np.pi/2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
print S&lt;br /&gt;
# na wydruku należy zauważyć, że wsółczynniki są zespolone i parami sprzężone&lt;br /&gt;
&lt;br /&gt;
# do pytania 2&lt;br /&gt;
(s,t) = sin(f=1,T=1,Fs=128,phi=np.pi/3) # f=0,10,30,64&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&lt;br /&gt;
# do pytania 3&lt;br /&gt;
(s,t) = delta(t0=0.5, T=1  ,Fs = 128)&lt;br /&gt;
&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(2)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Rekonstrukcja sygnału ze współczynników =====&lt;br /&gt;
Reprezentacja sygnałów w dziedzinie częstości jest dualna do reprezentacji  w dziedzinie czasu. To znaczy, że jedną reprezentację można przekształcić w drugą. Do przejścia z dziedziny czasu do częstości używaliśmy transformaty Fouriera (zaimplemantowanej w &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt;). Przejścia z dziedziny częstości do czasu dokonujemy przy pomocy odwrotnej transformaty Fouriera (zaimplementowanej jako &amp;lt;tt&amp;gt;ifft&amp;lt;/tt&amp;gt;. Mając (zespolone) współczynniki w dziedzinie częstości dla pewnego sygnału,możemy odzyskać jego przebieg czasowy.&lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał &amp;lt;math&amp;gt;s(t) = \sin(2\pi t \cdot 1)+\sin\left(2 \pi  t \cdot 3+\frac{\pi}{5}\right) &amp;lt;/math&amp;gt; o długości 2,5 s próbkowany 10 Hz, obliczyć jego transformatę Fouriera, a następnie zrekonstruować przebieg czasowy. Sygnał oryginalny i zrekonstruowany wykreślić na jednym rysunku.  Korzystając z naszych funkcji generację sygnału można zapisać tak:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
(s1,t) = sin(f=1, T=2.5, Fs=10, phi=0)&lt;br /&gt;
(s2,t) = sin(f=3, T=2.5, Fs=10, phi=np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Dla porównania proszę zrekonstruować sygnał korzystając jawnie z postaci odwrotnej transformaty Fouriera danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;x(n)=\frac{1}{N} \sum_{k=0}^{N-1} S[k] \cdot \exp\left(2j \pi n\frac{ k}{N}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
:Zwróćmy uwagę, że ''n'' w powyższym wzorze to indeksy punktów czasu, zatem wiążą się one z czasem zwracanym przez nasze funkcje następująco:&lt;br /&gt;
:&amp;lt;tt&amp;gt;n = np.arange(0,len(t),1)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
zatem kod rekonstruujący może być np. taki:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
n = np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
&lt;br /&gt;
def f1(dt):&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co dt	'''&lt;br /&gt;
	t = np.arange(0,2,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*t)+np.sin(2*np.pi*3*t+np.pi/5)#np.abs(t)#&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
dt = 0.1	&lt;br /&gt;
Fs = 1.0/dt&lt;br /&gt;
&lt;br /&gt;
(s1,t) = sin(f=1,T=2.5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2,t) = sin(f=3,T=2.5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
S = FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
N = len(t)&lt;br /&gt;
&lt;br /&gt;
s_ifft = FFT.ifft(S)&lt;br /&gt;
&lt;br /&gt;
n = np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.plot(t,s_ifft,'bo',markersize = 3 )&lt;br /&gt;
py.plot(t,(s_rekonstrukcja),'gx',markersize = 8)&lt;br /&gt;
py.plot(t,s,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Rekonstrukcja na dłuższym odcinku czasu:=====&lt;br /&gt;
Korzystając z wyników poprzedniego polecenia proszę porównać wykres funkcji zadanych wzorami dla odcinak czasu o długości 5s i rekonstrukcję sygnału o długości 5s otrzymanego ze współczynników Fouriera obliczonych dla 2,5s  odcinak czasu.&lt;br /&gt;
* Na jakim odcinku czasu sygnały są zgodne?&lt;br /&gt;
* Co dzieje się na dalszym odcinku czasu?&lt;br /&gt;
 *&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
dalszy ciąg poprzedniego kodu:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.figure(2)&lt;br /&gt;
(s1_d,t_d) = sin(f=1,T=5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2_d,t_d) = sin(f=3,T=5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s_d = s1_d + s2_d&lt;br /&gt;
&lt;br /&gt;
# rekonstrukcja bazująca na współczynnikach otzrzynmanych dla 2sek fragmentu sygnału&lt;br /&gt;
n=np.arange(0,len(t_d),1)&lt;br /&gt;
s_rekonstrukcja_dluga = np.zeros(len(t_d)) &lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja_dluga += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
py.plot(t_d,(s_rekonstrukcja_dluga),'gx-',markersize = 8)&lt;br /&gt;
py.plot(t_d,s_d,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Przykład:=====&lt;br /&gt;
Oblicz współczynniki numerycznie korzystając z &amp;lt;tt&amp;gt;numpy.fft.fft&amp;lt;/tt&amp;gt;, porównaj z otrzymanymi analitycznie. Zrób wykresy funkcji i wartości bezwzględnej transformaty. Dla funkcji ''f'' z poprzedniego przykładu danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt; f(t)=|t| &amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-1, 1]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1,&lt;br /&gt;
&lt;br /&gt;
Obliczamy współczynniki i robimy wykres:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def f1():&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co 0.1	'''&lt;br /&gt;
	dt = 0.1	&lt;br /&gt;
	t = np.arange(-1,1,dt)&lt;br /&gt;
	s = np.abs(t)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
Fs = 10.0&lt;br /&gt;
(s,t) = f1() #generuję sygnał&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.stem(t,s)&lt;br /&gt;
&lt;br /&gt;
S=FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
F = FFT.fftfreq(len(S),Fs) # obliczam skalę częstości &lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.stem(F,np.abs(S)/len(s)) # wykreślam widmo amplitudowe&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Porównujemy wyniki z wynikami analitycznymi:&lt;br /&gt;
* &amp;lt;math&amp;gt; f(t) = |cos(t)|&amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-\pi, \pi]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Efekt nieciągłości funkcji ====&lt;br /&gt;
* Wygenerować sinusoidę o następujących własnościach: f=10 Hz, T=1, Fs=100 Hz, i fazie = 1;&lt;br /&gt;
* Przy pomocy subplotów proszę sporządzić rysunek zgodnie z ponższym opisem:&lt;br /&gt;
** subplot(2,2,1): przebieg sygnału w czasie &lt;br /&gt;
** subplot(2,2,2): moduł jego transformaty Fouriera (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(len(s), 1/Fs)&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; to nasz sygnał),&lt;br /&gt;
** subplot(2,2,3): Proszę wykreślić trzykrotnie periodycznie powielony oryginalny sygnał. Można go skonstruować wywołując funkcję: &amp;lt;tt&amp;gt;s_period = np.concatenate((s,s,s))&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** subplot(2,2,4): moduł transformaty Fouriera &amp;lt;tt&amp;gt;s_period&amp;lt;/tt&amp;gt; (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(3*len(s), 1/Fs)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Powtórz te same kroki dla sinusa o częstości 10.3 Hz.&lt;br /&gt;
Pytania:&lt;br /&gt;
# Czym różnią się przedłużenia sinusoidy 10 Hz od sinusoidy 10.3 Hz? Proszę zwrócić uwagę na miejsca sklejania sygnałów. &amp;lt;!--Porównaj z wynikami otrzymanymi w zagadnieniu '''Rekonstrukcja na dłuższym odcinku czasu'''.--&amp;gt;&lt;br /&gt;
# Skąd bierze się widoczna różnica w widmie sinusoidy 10 Hz i 10.3 Hz? &lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s,t) = sin(f = 10.3, T =1, Fs = 100, phi = 1)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s))&lt;br /&gt;
t_period = np.arange(0,3,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Długość sygnału a rozdzielczość widma FFT ====&lt;br /&gt;
Z dotychczasowych rozważań o transformacie Fouriera ograniczonych w czasie sygnałów dyskretnych wynika, że w widmie reprezentowane są częstości od &amp;lt;math&amp;gt;-F_N&amp;lt;/math&amp;gt; do &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; to częstości Nyquista. Dostępnych binów częstości jest ''N'' - tyle samo ile obserwowanych punktów sygnału. Zatem zwiększenie długości sygnału w czasie poprawia &amp;quot;rozdzielczość&amp;quot;  reprezentacji częstotliwościowej sygnału. &lt;br /&gt;
&lt;br /&gt;
Załóżmy, że dysponujemy jedynie sekwencją ''N'' próbek pewnego sygnału. Rozważymy teraz jakie można przyjąć strategie przedłużania tego sygnału w celu zwiększenia gęstości binów częstotliwościowych i jakie te strategie mają konsekwencje.&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Przedłużenie przez periodyczną replikację =====&lt;br /&gt;
Rozważając poprzednie przykłady zauważyliśmy, że FFT &amp;quot;widzi&amp;quot; sygnał tak jakby to była nieskończona periodyczna replikacja fragmentu sygnału podanego na wejście. Zatem najbardziej naturalną formą przedłużenia sygnału może wydawać się postępowanie zgodnie z tym sposobem widzenia i dołożenie do sygnału kolejnych segmentów zawierających kopie analizowanego fragmentu sygnału. Zbadajmy empirycznie efekty takiego podejścia. &lt;br /&gt;
&lt;br /&gt;
* Proszę wytworzyć i wykreślić sinusoidy o częstościach 15 i 20 Hz, trwające 0.1s i próbkowane 100Hz. &lt;br /&gt;
** Ile próbek sygnału dostajemy?&lt;br /&gt;
** Proszę obliczyć transformatę Fouriera. Ile punktów w widmie amplitudowym otrzymujemy? Dla jakich cżęstości mamy biny?&lt;br /&gt;
** Proszę skonstruować sygnał będący złożeniem 10 kopii oryginalnego sygnału. &lt;br /&gt;
Jest to 10-krotnie dłuższy fragment sygnału, którego wersję nieskończoną opisują współczynniki obliczone przez transformatę Fouriera. Transformata policzona z takiego wydłużonego odcinak ma 10-krotnie więcej binów. W szczególności zawiera on bin 15Hz. Proszę porównać wykresy widma amplitudowego otrzymanego dla wersji krótkiej i przedłużonej sygnału. Czy wynik jest zaskakujący? Jak go można zrozumieć?&lt;br /&gt;
 * Sygnał przedłużony periodycznie nie zawiera żadnej dodatkowej informacji względem pojedynczego okresu!&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s,s,s,s,s,s,s,s))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Przedłużanie sygnału zerami =====&lt;br /&gt;
Inną popularną metodą na zwiększanie ilości binów w transformacie Fouriera jest przedłużanie sygnału zerami (zero-padding). Jest to szczególny przypadek następującego podejścia: Nasz &amp;quot;prawdziwy&amp;quot; sygnał jest długi. Oglądamy go przez prostokątne okno, które ma wartość 1 na odcinku czasu dla którego próbki mamy dostępne i 0 dla pozostałego czasu (więcej o różnych oknach będzie na kolejnych zajęciach). W efekcie możemy myśleć, że oglądany przez nas sygnał to efekt przemnożenia &amp;quot;prawdziwego&amp;quot; sygnału przez okno. Efekty takiego przedłużania proszę zbadać przy użyciu poniższego kodu. &lt;br /&gt;
* Jak można zinterpretować wyniki tego eksperymentu w świetle [[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|twierdzenia o splocie]]?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,z,z,z,z,z,z,z,z,z))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S))&lt;br /&gt;
py.stem(F,np.abs(S)/len(S),linefmt='r-', markerfmt='ro')&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4248</id>
		<title>Ćwiczenia 2 2</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4248"/>
		<updated>2015-10-05T19:03:35Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Rekonstrukcja sygnału ze współczynników */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Zadania ===&lt;br /&gt;
&lt;br /&gt;
==== Współczynniki obliczane przez FFT ====&lt;br /&gt;
Najprostsza sytuacja: Badamy współczynniki zwracane przez &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt; dla sinusoid o różnych częstościach. Wykorzystujemy funkcje do generacji sygnałów napisane na poprzednich zajęciach.&lt;br /&gt;
&lt;br /&gt;
* Proszę kolejno wygenerować sinusoidy o długości 1s próbkowaną 128Hz i częstościach 1,10,30, 64  i  0 Hz. Dla tych sinusoid proszę policzyć transformaty Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wyglądają otrzymane wykresy?&lt;br /&gt;
** Czy coś szczególnego dzieje się dla częstości 0 i 64Hz? Czy w tych skrajnych przypadkach faza sygnału ma wpływ na wynik transformaty? &lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał delta położony w sekundzie 0,5 na odcinku czasu o długości 1s próbkowany 128Hz. Dla takiego sygnału proszę policzyć transformatę Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wygląda transformata funkcji delta? Jakie częstości w sobie zawiera?&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
# skrypt implemetujący polecenia w sekcji&lt;br /&gt;
# Współczynniki obliczane przez FFT&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
def delta(t0=0.5, T=1  ,Fs = 128):&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	d = np.zeros(len(t))&lt;br /&gt;
	d[np.ceil(t0*Fs)]=1&lt;br /&gt;
	return (d,t)&lt;br /&gt;
 &lt;br /&gt;
# do pytania 1&lt;br /&gt;
(s,t) = sin(f=2,T=1,Fs=10,phi=np.pi/2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
print S&lt;br /&gt;
# na wydruku należy zauważyć, że wsółczynniki są zespolone i parami sprzężone&lt;br /&gt;
&lt;br /&gt;
# do pytania 2&lt;br /&gt;
(s,t) = sin(f=1,T=1,Fs=128,phi=np.pi/3) # f=0,10,30,64&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&lt;br /&gt;
# do pytania 3&lt;br /&gt;
(s,t) = delta(t0=0.5, T=1  ,Fs = 128)&lt;br /&gt;
&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(2)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Rekonstrukcja sygnału ze współczynników =====&lt;br /&gt;
Reprezentacja sygnałów w dziedzinie częstości jest dualna do reprezentacji  w dziedzinie czasu. To znaczy, że jedną reprezentację można przekształcić w drugą. Do przejścia z dziedziny czasu do częstości używaliśmy transformaty Fouriera (zaimplemantowanej w &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt;). Przejścia z dziedziny częstości do czasu dokonujemy przy pomocy odwrotnej transformaty Fouriera (zaimplementowanej jako &amp;lt;tt&amp;gt;ifft&amp;lt;/tt&amp;gt;. Mając (zespolone) współczynniki w dziedzinie częstości dla pewnego sygnału,możemy odzyskać jego przebieg czasowy.&lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał &amp;lt;math&amp;gt;s(t) = \sin(2\pi t \cdot 1)+\sin\left(2 \pi  t \cdot 3+\frac{\pi}{5}\right) &amp;lt;/math&amp;gt; o długości 2,5s próbkowany 10Hz, obliczyć jego transformatę Fouriera, a następnie zrekonstruować przebieg czasowy. Sygnał oryginalny i zrekonstruowany wykreślić na jednym rysunku.  Korzystając z naszych funkcji generację sygnału można zapisać tak:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
(s1,t) = sin(f=1, T=2.5, Fs=10, phi=0)&lt;br /&gt;
(s2,t) = sin(f=3, T=2.5, Fs=10, phi=np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Dla porównania proszę zrekonstruować sygnał korzystając jawnie z postaci odwrotnej transformaty Fouriera danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;x(n)=\frac{1}{N} \sum_{k=0}^{N-1} S[k] \cdot \exp\left(2j \pi n\frac{ k}{N}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
:Zwróćmy uwagę, że ''n'' w powyższym wzorze to indeksy punktów czasu, zatem wiążą się one z czasem zwracanym przez nasze funkcje następująco:&lt;br /&gt;
:&amp;lt;tt&amp;gt;n=np.arange(0,len(t),1)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
zatem kod rekonstruujący może być np. taki:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
n = np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
&lt;br /&gt;
def f1(dt):&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co dt	'''&lt;br /&gt;
	t = np.arange(0,2,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*t)+np.sin(2*np.pi*3*t+np.pi/5)#np.abs(t)#&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
dt = 0.1	&lt;br /&gt;
Fs = 1.0/dt&lt;br /&gt;
&lt;br /&gt;
(s1,t) = sin(f=1,T=2.5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2,t) = sin(f=3,T=2.5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
S = FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
N = len(t)&lt;br /&gt;
&lt;br /&gt;
s_ifft = FFT.ifft(S)&lt;br /&gt;
&lt;br /&gt;
n = np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.plot(t,s_ifft,'bo',markersize = 3 )&lt;br /&gt;
py.plot(t,(s_rekonstrukcja),'gx',markersize = 8)&lt;br /&gt;
py.plot(t,s,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Rekonstrukcja na dłuższym odcinku czasu:=====&lt;br /&gt;
Korzystając z wyników poprzedniego polecenia proszę porównać wykres funkcji zadanych wzorami dla odcinak czasu o długości 5s i rekonstrukcję sygnału o długości 5s otrzymanego ze współczynników Fouriera obliczonych dla 2,5s  odcinak czasu.&lt;br /&gt;
* Na jakim odcinku czasu sygnały są zgodne?&lt;br /&gt;
* Co dzieje się na dalszym odcinku czasu?&lt;br /&gt;
 *&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
dalszy ciąg poprzedniego kodu:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.figure(2)&lt;br /&gt;
(s1_d,t_d) = sin(f=1,T=5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2_d,t_d) = sin(f=3,T=5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s_d = s1_d + s2_d&lt;br /&gt;
&lt;br /&gt;
# rekonstrukcja bazująca na współczynnikach otzrzynmanych dla 2sek fragmentu sygnału&lt;br /&gt;
n=np.arange(0,len(t_d),1)&lt;br /&gt;
s_rekonstrukcja_dluga = np.zeros(len(t_d)) &lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja_dluga += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
py.plot(t_d,(s_rekonstrukcja_dluga),'gx-',markersize = 8)&lt;br /&gt;
py.plot(t_d,s_d,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Przykład:=====&lt;br /&gt;
Oblicz współczynniki numerycznie korzystając z &amp;lt;tt&amp;gt;numpy.fft.fft&amp;lt;/tt&amp;gt;, porównaj z otrzymanymi analitycznie. Zrób wykresy funkcji i wartości bezwzględnej transformaty. Dla funkcji ''f'' z poprzedniego przykładu danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt; f(t)=|t| &amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-1, 1]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1,&lt;br /&gt;
&lt;br /&gt;
Obliczamy współczynniki i robimy wykres:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def f1():&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co 0.1	'''&lt;br /&gt;
	dt = 0.1	&lt;br /&gt;
	t = np.arange(-1,1,dt)&lt;br /&gt;
	s = np.abs(t)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
Fs = 10.0&lt;br /&gt;
(s,t) = f1() #generuję sygnał&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.stem(t,s)&lt;br /&gt;
&lt;br /&gt;
S=FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
F = FFT.fftfreq(len(S),Fs) # obliczam skalę częstości &lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.stem(F,np.abs(S)/len(s)) # wykreślam widmo amplitudowe&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Porównujemy wyniki z wynikami analitycznymi:&lt;br /&gt;
* &amp;lt;math&amp;gt; f(t) = |cos(t)|&amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-\pi, \pi]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Efekt nieciągłości funkcji ====&lt;br /&gt;
* Wygenerować sinusoidę o następujących własnościach: f=10 Hz, T=1, Fs=100 Hz, i fazie = 1;&lt;br /&gt;
* Przy pomocy subplotów proszę sporządzić rysunek zgodnie z ponższym opisem:&lt;br /&gt;
** subplot(2,2,1): przebieg sygnału w czasie &lt;br /&gt;
** subplot(2,2,2): moduł jego transformaty Fouriera (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(len(s), 1/Fs)&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; to nasz sygnał),&lt;br /&gt;
** subplot(2,2,3): Proszę wykreślić trzykrotnie periodycznie powielony oryginalny sygnał. Można go skonstruować wywołując funkcję: &amp;lt;tt&amp;gt;s_period = np.concatenate((s,s,s))&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** subplot(2,2,4): moduł transformaty Fouriera &amp;lt;tt&amp;gt;s_period&amp;lt;/tt&amp;gt; (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(3*len(s), 1/Fs)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Powtórz te same kroki dla sinusa o częstości 10.3 Hz.&lt;br /&gt;
Pytania:&lt;br /&gt;
# Czym różnią się przedłużenia sinusoidy 10 Hz od sinusoidy 10.3 Hz? Proszę zwrócić uwagę na miejsca sklejania sygnałów. &amp;lt;!--Porównaj z wynikami otrzymanymi w zagadnieniu '''Rekonstrukcja na dłuższym odcinku czasu'''.--&amp;gt;&lt;br /&gt;
# Skąd bierze się widoczna różnica w widmie sinusoidy 10 Hz i 10.3 Hz? &lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s,t) = sin(f = 10.3, T =1, Fs = 100, phi = 1)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s))&lt;br /&gt;
t_period = np.arange(0,3,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Długość sygnału a rozdzielczość widma FFT ====&lt;br /&gt;
Z dotychczasowych rozważań o transformacie Fouriera ograniczonych w czasie sygnałów dyskretnych wynika, że w widmie reprezentowane są częstości od &amp;lt;math&amp;gt;-F_N&amp;lt;/math&amp;gt; do &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; to częstości Nyquista. Dostępnych binów częstości jest ''N'' - tyle samo ile obserwowanych punktów sygnału. Zatem zwiększenie długości sygnału w czasie poprawia &amp;quot;rozdzielczość&amp;quot;  reprezentacji częstotliwościowej sygnału. &lt;br /&gt;
&lt;br /&gt;
Załóżmy, że dysponujemy jedynie sekwencją ''N'' próbek pewnego sygnału. Rozważymy teraz jakie można przyjąć strategie przedłużania tego sygnału w celu zwiększenia gęstości binów częstotliwościowych i jakie te strategie mają konsekwencje.&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Przedłużenie przez periodyczną replikację =====&lt;br /&gt;
Rozważając poprzednie przykłady zauważyliśmy, że FFT &amp;quot;widzi&amp;quot; sygnał tak jakby to była nieskończona periodyczna replikacja fragmentu sygnału podanego na wejście. Zatem najbardziej naturalną formą przedłużenia sygnału może wydawać się postępowanie zgodnie z tym sposobem widzenia i dołożenie do sygnału kolejnych segmentów zawierających kopie analizowanego fragmentu sygnału. Zbadajmy empirycznie efekty takiego podejścia. &lt;br /&gt;
&lt;br /&gt;
* Proszę wytworzyć i wykreślić sinusoidy o częstościach 15 i 20 Hz, trwające 0.1s i próbkowane 100Hz. &lt;br /&gt;
** Ile próbek sygnału dostajemy?&lt;br /&gt;
** Proszę obliczyć transformatę Fouriera. Ile punktów w widmie amplitudowym otrzymujemy? Dla jakich cżęstości mamy biny?&lt;br /&gt;
** Proszę skonstruować sygnał będący złożeniem 10 kopii oryginalnego sygnału. &lt;br /&gt;
Jest to 10-krotnie dłuższy fragment sygnału, którego wersję nieskończoną opisują współczynniki obliczone przez transformatę Fouriera. Transformata policzona z takiego wydłużonego odcinak ma 10-krotnie więcej binów. W szczególności zawiera on bin 15Hz. Proszę porównać wykresy widma amplitudowego otrzymanego dla wersji krótkiej i przedłużonej sygnału. Czy wynik jest zaskakujący? Jak go można zrozumieć?&lt;br /&gt;
 * Sygnał przedłużony periodycznie nie zawiera żadnej dodatkowej informacji względem pojedynczego okresu!&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s,s,s,s,s,s,s,s))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Przedłużanie sygnału zerami =====&lt;br /&gt;
Inną popularną metodą na zwiększanie ilości binów w transformacie Fouriera jest przedłużanie sygnału zerami (zero-padding). Jest to szczególny przypadek następującego podejścia: Nasz &amp;quot;prawdziwy&amp;quot; sygnał jest długi. Oglądamy go przez prostokątne okno, które ma wartość 1 na odcinku czasu dla którego próbki mamy dostępne i 0 dla pozostałego czasu (więcej o różnych oknach będzie na kolejnych zajęciach). W efekcie możemy myśleć, że oglądany przez nas sygnał to efekt przemnożenia &amp;quot;prawdziwego&amp;quot; sygnału przez okno. Efekty takiego przedłużania proszę zbadać przy użyciu poniższego kodu. &lt;br /&gt;
* Jak można zinterpretować wyniki tego eksperymentu w świetle [[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|twierdzenia o splocie]]?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,z,z,z,z,z,z,z,z,z))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S))&lt;br /&gt;
py.stem(F,np.abs(S)/len(S),linefmt='r-', markerfmt='ro')&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=Nieparametryczne_widmo_mocy&amp;diff=4247</id>
		<title>Nieparametryczne widmo mocy</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=Nieparametryczne_widmo_mocy&amp;diff=4247"/>
		<updated>2015-10-05T10:20:14Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Sygnały stochastyczne */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Widmo mocy==&lt;br /&gt;
=== Moc===&lt;br /&gt;
Moc chwilowa sygnału przez analogię do układów elektrycznych o jednostkowym oporze jest w analizie sygnałów przyjęta jako kwadraty próbek (&amp;lt;math&amp;gt;P = I^2 R = \frac{U^2}{R}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Oznaczmy sygnał &lt;br /&gt;
&amp;lt;math&amp;gt;x[n]&amp;lt;/math&amp;gt;, wówczas jego moc wyraża się wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;P[n]=x[n]^2&amp;lt;/math&amp;gt;, &lt;br /&gt;
a energia wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;E = \sum _n{x[n]^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
==== Zadanie ====&lt;br /&gt;
Przy pomocy funkcji napisanych na poprzednich zajęciach proszę wygenerować sygnał sinusoidalny o amplitudzie 1, częstości 10 Hz, trwający 0.3 sekundy i próbkowany z częstością 1000 Hz. Proszę narysować ten sygnał przy pomocy funkcji &amp;lt;tt&amp;gt;pylab.stem&amp;lt;/tt&amp;gt;, obliczyć i narysować przebieg mocy w czasie, obliczyć energię tego sygnału.&lt;br /&gt;
&lt;br /&gt;
===Widmo mocy: tw. Plancherela i tw. Parsevala ===&lt;br /&gt;
Twierdzenia te omawiane i dowodzone były na [[Szereg_Fouriera#To.C5.BCsamo.C5.9B.C4.87_Parsevala_dla_szereg.C3.B3w_Fouriera|wykładzie]]. Tutaj, tylko krótko przypomnijmy sobie: &lt;br /&gt;
====Twierdzenie Plancherela====&lt;br /&gt;
Jeśli &amp;lt;math&amp;gt;X[k]&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;Y[k]&amp;lt;/math&amp;gt; są transformatami &amp;lt;math&amp;gt;x[n]&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;y[n]&amp;lt;/math&amp;gt; odpowiednio to:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid15&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\sum _{n=0}^{N-1} x[n]y^*[n] = \frac{1}{N} \sum _{k=0}^{N-1} X[k] Y^*[k]&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
gwiazdka oznacza sorzężenie zespolone. &lt;br /&gt;
====Twierdzenie Parsevala====&lt;br /&gt;
jest specjalnym przypadkiem twierdzenia Plancherela:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid16&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\sum _{n=0}^{N-1} \left|x[n]\right|^2 = \frac{1}{N} \sum _{k=0}^{N-1} \left|X[k]\right|^2.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
Twierdzenie to upoważnia nas do utożsamiania kwadratów wartości bezwzględnej składowych transformaty Fouriera z mocą niesioną przez odpowiadające im składowe.&lt;br /&gt;
&lt;br /&gt;
=== Zadanie: funkcja do estymacji widma mocy ===&lt;br /&gt;
Proszę napisać i przetestować funkcję realizującą następujący algorytm estymacji widma mocy:&lt;br /&gt;
# Jako parametry funkcja przyjmuje sygnał &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; i częstość próbkowania tego sygnału&lt;br /&gt;
# Oblicz transformatę Fouriera sygnału przy pomocy &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Unormuj otrzymaną transformatę przez pierwiastek z ilości próbek sygnału&lt;br /&gt;
# Oblicz moc jako iloczyn unormowanej transformaty i jej sprzężenia zespolonego. W pythonie sprzężenie zespolone liczby &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; otrzymujemy korzystając z metody &amp;lt;tt&amp;gt;S.conj()&amp;lt;/tt&amp;gt;. W wyniku powyższego iloczynu dostaniemy liczby zespolone o zerowej części urojonej (proszę to sprawdzić). &lt;br /&gt;
# Do dalszych operacji wybierz tylko część rzeczywistą mocy. Część rzeczywistą liczby zespolonej M pobieramy w następujący sposób: &amp;lt;tt&amp;gt;czesc_rzeczywista_M = M.real&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Korzystając z funkcji &amp;lt;tt&amp;gt;fftfreq&amp;lt;/tt&amp;gt; obliczamy częstości, dla których policzone są współczynniki Fouriera.&lt;br /&gt;
# Przy pomocy funkcji &amp;lt;tt&amp;gt;fftshift&amp;lt;/tt&amp;gt; porządkujemy kolejność wektorów mocy i częstości, tak aby częstości były reprezentowane od -częstości Nyquista, przez 0, do +częstości Nyquista&lt;br /&gt;
# zwracamy uporządkowane wektory mocy i częstości&lt;br /&gt;
&lt;br /&gt;
Testowanie:&lt;br /&gt;
&lt;br /&gt;
# przy pomocy funkcji sin napisanej na drugich ćwiczeniach  wygeneruj sinusoidę o długości 1 s, o częstości 10Hz, próbkowaną 100 Hz.&lt;br /&gt;
# oblicz moc w czasie (trzeba podnieść wartość każdej próbki do kwadratu)&lt;br /&gt;
# oblicz moc w częstości przy pomocy funkcji estymacji widma mocy&lt;br /&gt;
# oblicz energię sygnału w czasie&lt;br /&gt;
# oblicz energię sygnału w częstości&lt;br /&gt;
# wykreśl: &lt;br /&gt;
#* sygnał&lt;br /&gt;
#* przebieg jego mocy w czasie&lt;br /&gt;
#* przebieg mocy w częstości&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import rfft,fft,fftfreq,fftshift&lt;br /&gt;
 &lt;br /&gt;
def widmo_mocy(s, Fs):&lt;br /&gt;
    S = fft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = S*S.conj()&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (fftshift(S_moc),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
(s,t) = sin(f=10,Fs=100.0)&lt;br /&gt;
moc_w_czasie = s**2&lt;br /&gt;
(moc_w_czestosci, F) = widmo_mocy(s, Fs=100.0)&lt;br /&gt;
&lt;br /&gt;
energia_w_czasie = np.sum(moc_w_czasie)&lt;br /&gt;
energia_w_czestosci = np.sum(moc_w_czestosci)&lt;br /&gt;
print 'energia w czasie: ', energia_w_czasie&lt;br /&gt;
print 'energia w czestosci: ', energia_w_czestosci&lt;br /&gt;
&lt;br /&gt;
py.subplot(3,1,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title('Sygnał')&lt;br /&gt;
py.subplot(3,1,2)&lt;br /&gt;
py.plot(t,moc_w_czasie)&lt;br /&gt;
py.title('moc w czasie')&lt;br /&gt;
py.subplot(3,1,3)&lt;br /&gt;
py.plot(F,moc_w_czestosci)&lt;br /&gt;
py.title('moc w częstości')&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===Rozdzielczość widma===&lt;br /&gt;
Proszę zbadać rozdzielczość częstotliwościową widma w zależności od długości sygnału. Używamy funkcji &amp;lt;tt&amp;gt;m_sin&amp;lt;/tt&amp;gt;. Zwrócić uwagę na to co dzieje się na końcach odcinka.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Okienkowanie a widmo mocy: periodogram===&lt;br /&gt;
Przypomnijmy wzór na dyskretną transformatę Fouriera [http://brain.fuw.edu.pl/edu/%C4%86wiczenia_2#Dyskretna_Transformata_Fouriera_.28DFT.29 DFT] zaimplementowaną w FFT: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;S[k] =  \sum_{n=0}^{n-1} s[n] \exp\left\{-2\pi i{nk \over N}\right\}       \qquad k = 0,\ldots,N-1.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Na podstawie twierdzenia [[Nieparametryczne_widmo_mocy#Twierdzenie_Parsevala|Parsevala]] możemy policzyć widmo mocy jako:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P[k] = \frac{1}{N}  \left|S[k]\right|^2 &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jeśli do liczenia mocy chcielibyśmy posłużyć się techniką okiennkowania sygnału, to powinniśmy używać okienek znormalizowanych, czyli takich których energia jest równa 1, wtedy mnożenie przez okienko nie zaburzy estymaty energii sygnału. &lt;br /&gt;
&lt;br /&gt;
Aby policzyć widmo mocy sygnału z zastosowaniem okienek wprowadzimy następujące symbole:&lt;br /&gt;
* sygnał: &amp;lt;math&amp;gt;s[n]&amp;lt;/math&amp;gt;&lt;br /&gt;
* okienko: &amp;lt;math&amp;gt; w[n]&amp;lt;/math&amp;gt;&lt;br /&gt;
* okienko znormalizowane: &amp;lt;math&amp;gt; \hat w[n] = \frac{1}{\sqrt{\sum_{n=0}^{N-1} (w[n])^2}}w[n]&amp;lt;/math&amp;gt; &lt;br /&gt;
&amp;lt;!--(w szczególnym przypadku okienka prostokątnego normalizacja ta daje &amp;lt;math&amp;gt;1/N^2&amp;lt;/math&amp;gt; występujące we wzorze na moc)--&amp;gt;&lt;br /&gt;
* widmo mocy sygnału okienkowanego:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P[k] = \frac{1}{\sum_{n=0}^{N-1} (w[n])^2}  \left|\sum_{n=0}^{N-1} s[n]w[n] e^{i\frac{2 \pi }{N} k n}\right|^2 &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Zadanie ====&lt;br /&gt;
Proszę napisać funkcję obliczającą periodogram.&lt;br /&gt;
Funkcja jako argumenty powinna przyjmować sygnał, okno (podane jako sekwencja próbek), i częstość próbkowania. Zwracać powinna widmo mocy i skalę osi częstości. Wewnątrz funkcja powinna implementować liczenie widma z sygnału okienkowanego znormalizowanym oknem.&lt;br /&gt;
&lt;br /&gt;
Funkcję proszę przetestować obliczając dla funkcji sinus energię sygnału w dziedzinie czasu i w dziedzinie częstości. Testy proszę wykonać dla okna prostokątnego, Blackmana i Haminga.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , F_samp):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    F_samp- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 10.1, T =2, Fs = F_samp, phi = 0)&lt;br /&gt;
N = len(x) # dłogość sygnału&lt;br /&gt;
okno = np.ones(N)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N)&lt;br /&gt;
#okno = np.hamming(N)&lt;br /&gt;
&lt;br /&gt;
s = x*okno # sygnał okienkowany&lt;br /&gt;
#&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,x)&lt;br /&gt;
energia_t = np.sum(x**2)&lt;br /&gt;
print 'energia sygnału:', energia_t&lt;br /&gt;
py.title(u' sygnał')&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał')&lt;br /&gt;
py.title(u' sygnał okienkowany ')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
(S,F) = widmo_dB(s,N,F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego')&lt;br /&gt;
py.ylabel('dB')&lt;br /&gt;
&lt;br /&gt;
#periodogram&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
(P, F) = periodogram(x,okno,F_samp)&lt;br /&gt;
py.plot(F,P)&lt;br /&gt;
        &lt;br /&gt;
py.title('periodogram')&lt;br /&gt;
print 'energia periodogramu:', np.sum(P)&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Sygnały stochastyczne ==&lt;br /&gt;
Sygnał stochastyczny to taki sygnał, dla którego ciągu próbek nie da się opisać funkcją czasu. Kolejne próbki w takim sygnale to [[Zmienne_losowe_i_generatory_liczb_pseudolosowych#Zmienna_losowa|zmienne losowe]]. Można je opisać podając własności [[Zmienne_losowe_i_generatory_liczb_pseudolosowych#Rozk.C5.82ad_prawdopodobie.C5.84stwa|rozkładu]], z k†órego pochodzą. Często w opisie takich zmiennych posługujemy się [[WnioskowanieStatystyczne/Zmienne_losowe_i_generatory_liczb_pseudolosowych#Momenty|momentami rozkładów]].&lt;br /&gt;
Jak można sobie wyobrazić rozkłady, z których pochodzą próbki?&lt;br /&gt;
Można sobie wyobrazić,że obserwowany przez nas sygnał stochastyczny to jedna z możliwych realizacji procesu stochastycznego. &lt;br /&gt;
Jeśli &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; jest zbiorem &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; zdarzeń (&amp;lt;math&amp;gt;k \in K&amp;lt;/math&amp;gt;) i każde z tych zdarzeń ma przypisaną funkcję &amp;lt;math&amp;gt;x_k(t)&amp;lt;/math&amp;gt; zwaną realizacją procesu &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt;, to proces stochastyczny może być zdefiniowany jako zbiór funkcji:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid23&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\xi (t) = \left\lbrace x_1(t),x_2(t),\dots , x_N(t) \right\rbrace &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;x_k(t)&amp;lt;/math&amp;gt; są losowymi funkcjami czasu &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Procesy stochastyczne można opisywać prze wartości oczekiwane liczone po realizacjach.&lt;br /&gt;
&lt;br /&gt;
Dla przypomnienia wartość oczekiwaną liczymy tak:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid24&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
{\mu _x(t_1) = E\left[\xi (t_1) \right]= \lim _{N \rightarrow \infty }\sum _{k=1}^{N}{x_k(t_1)} p(x_k,t_1)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
średnia &amp;lt;math&amp;gt;\mu _x(t_1)&amp;lt;/math&amp;gt; procesu &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt; w chwili &amp;lt;math&amp;gt;t_1&amp;lt;/math&amp;gt; to suma wartośći zaobserwowanych w chwili we wszystkich realizacjach &amp;lt;math&amp;gt;t_1&amp;lt;/math&amp;gt; ważona prawdopodobieństwem wystąpienia tej realizacji:&lt;br /&gt;
=== Stacjonarność i ergodyczność===&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
	&amp;lt;dt&amp;gt;&lt;br /&gt;
	Stacjonarność:&lt;br /&gt;
	&amp;lt;dd&amp;gt;&lt;br /&gt;
	Jeśli dla procesu stochastycznego &amp;lt;math&amp;gt;\xi (t)&amp;lt;/math&amp;gt; wszystkie momenty są niezależne od czasu to jest on stajonarny w ścisłym sensie. Jeśli tylko średnia &amp;lt;math&amp;gt;\mu _x&amp;lt;/math&amp;gt; i autokorelacja &amp;lt;math&amp;gt;R_x(\tau )&amp;lt;/math&amp;gt; nie zależą od czasu to proces jest stacjonarny w słabym sensie, co dla wielu zastosowań jest wystarczające.&lt;br /&gt;
	&amp;lt;dt&amp;gt;&lt;br /&gt;
	Ergodyczność:&lt;br /&gt;
	&amp;lt;dd&amp;gt;&lt;br /&gt;
	Proces jest ergodyczny jeśli jego średnie po czasie i po realizacjach są sobie równe. Oznacza to, że dla takiego procesu jedna realizacja jest reprezentatywna i zawiera całą informację o tym procesie.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Założenie o sygnale, że jest stacjonarny i ergodyczny pozwala zamienić sumowanie po realizacjach na sumowanie po czasie w estymatory momentów statystycznych.&lt;br /&gt;
&lt;br /&gt;
===Transformata Fouriera sygnału stochastycznego===&lt;br /&gt;
Bardzo często musimy oszacować widmo mocy sygnału zawierającego znaczny udział szumu.&lt;br /&gt;
&lt;br /&gt;
Poniższe ćwiczenie ilustruje niepewność szacowania pików w widmie otrzymanym z transformaty Fouriera dla sygnału zawierającego szum.&lt;br /&gt;
&lt;br /&gt;
* wygeneruj 20 realizacji sygnału będącego sumą sinusoidy (f=20Hz, T=1s, Fs =100Hz) i  szumu gaussowskiego&lt;br /&gt;
* dla każdej realizacji oblicz widmo mocy&lt;br /&gt;
* wykreśl wszystkie otrzymane widma na wspólnym wykresie&lt;br /&gt;
&lt;br /&gt;
Proszę obejrzeć otrzymane widma.&lt;br /&gt;
* Zaobserwuj jakiego rzędu jest niepewność wyniku.&lt;br /&gt;
* Czy podobny problem występuje dla sygnału bez szumu?&lt;br /&gt;
* Skonstruuj funkcję rysującą średnie widmo wraz z [[Przedzia%C5%82y_ufno%C5%9Bci#Zadanie_2 95%|przedziałem ufności]].&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import scipy.stats as st&lt;br /&gt;
&lt;br /&gt;
from numpy.fft import rfft,fft,fftfreq,fftshift&lt;br /&gt;
 &lt;br /&gt;
def widmo_mocy(s, Fs):&lt;br /&gt;
    '''funkcja oblicza widmo mocy sygnału i oś częstości&lt;br /&gt;
    s - sygnał&lt;br /&gt;
    Fs - częstość próbkowania&lt;br /&gt;
    '''&lt;br /&gt;
    S = fft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = S*S.conj()&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (fftshift(S_moc),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
def widmo_mocy_rzeczywistego(s,FS):&lt;br /&gt;
    '''funkcja oblicza widmo mocy sygnału rzeczywistego i oś częstości&lt;br /&gt;
    s - sygnał&lt;br /&gt;
    Fs - częstość próbkowania&lt;br /&gt;
&lt;br /&gt;
    zwraca dodatnią część widma&lt;br /&gt;
    '''&lt;br /&gt;
    S = rfft(s)/np.sqrt(len(s))&lt;br /&gt;
    S_moc = np.abs(S)**2&lt;br /&gt;
    S_moc = S_moc.real&lt;br /&gt;
    F = fftfreq(len(s), 1/Fs)&lt;br /&gt;
    return (S_moc,F)&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def szum(mu =0 , sigma = 1, T = 1, Fs = 128):&lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.random.randn(len(t) )*sigma + mu&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def dwadziescia_realizacji(FS):&lt;br /&gt;
    '''&lt;br /&gt;
    *  wygeneruj 20 realizacji sygnału będącego sumą sinusoidy (f=20Hz, T=1s, Fs =100Hz) i szumu gassowskiego&lt;br /&gt;
    * dla każdej realizacji oblicz widmo mocy&lt;br /&gt;
    * wykreśl wszystkie otrzymane widma na wspólnym wykresie &lt;br /&gt;
    '''&lt;br /&gt;
    for i in range(20):&lt;br /&gt;
        (s,t) = sin(f=10,Fs=FS)&lt;br /&gt;
        (sz,t) = szum(Fs =FS)&lt;br /&gt;
        syg = s + sz&lt;br /&gt;
        (moc_w_czestosci, F) = widmo_mocy(syg, Fs=FS)&lt;br /&gt;
        py.plot(F,moc_w_czestosci)&lt;br /&gt;
    py.show()&lt;br /&gt;
    &lt;br /&gt;
def srednie_widmo(FS):&lt;br /&gt;
    '''&lt;br /&gt;
    #  Skonstruuj funkcję rysującą średnie widmo wraz z 95% przedziałem ufności. &lt;br /&gt;
    '''&lt;br /&gt;
    zbior_widm = np.zeros((20,FS))&lt;br /&gt;
    for i in range(20):&lt;br /&gt;
        (s,t) = sin(f=10,Fs=FS)&lt;br /&gt;
        (sz,t) = szum(Fs =FS)&lt;br /&gt;
        syg = s + sz&lt;br /&gt;
        (moc_w_czestosci, F) = widmo_mocy(syg, Fs=FS)&lt;br /&gt;
        zbior_widm[i][:] = moc_w_czestosci&lt;br /&gt;
    srednie_w = np.mean(zbior_widm,axis =0)&lt;br /&gt;
    przedzial_d = np.zeros(len(F))&lt;br /&gt;
    przedzial_g = np.zeros(len(F))&lt;br /&gt;
    for f in F:&lt;br /&gt;
        przedzial_d[f] = st.scoreatpercentile(zbior_widm[:,f], 2.5)&lt;br /&gt;
        przedzial_g[f] = st.scoreatpercentile(zbior_widm[:,f], 97.5)&lt;br /&gt;
    py.plot(F,srednie_w,'r')&lt;br /&gt;
    py.plot(F,przedzial_d,'b')&lt;br /&gt;
    py.plot(F,przedzial_g,'b')&lt;br /&gt;
    py.show()&lt;br /&gt;
&lt;br /&gt;
FS =100.0    &lt;br /&gt;
#dwadziescia_realizacji(FS)&lt;br /&gt;
srednie_widmo(FS)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Oszacowanie błędu transformaty Fouriera dla białego szumu ===&lt;br /&gt;
Dla sygnału stochastycznego &amp;lt;math&amp;gt;x(t)&amp;lt;/math&amp;gt;, którego kolejne próbki pochodzą z niezależnych rozkładów normalnych (biały szum), jego transformata Fouriera &amp;lt;math&amp;gt;X(f)&amp;lt;/math&amp;gt; jest liczbą zespoloną, której część rzeczywista &amp;lt;math&amp;gt;X_R(f)&amp;lt;/math&amp;gt; i urojona &amp;lt;math&amp;gt;X_I(f)&amp;lt;/math&amp;gt; mogą być uznane za nieskorelowane zmienne losowe o średniej zero i równych wariancjach. Ponieważ transformata Fouriera jest operacją liniową więc składowe  &amp;lt;math&amp;gt;X_R(f)&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;X_I(f)&amp;lt;/math&amp;gt; mają rozkłady normalne. Zatem wielkość:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P(f) = |X(f)|^2 = X_R^2(f) + X_I^2(f)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
jest sumą kwadratów dwóch niezależnych zmiennych normalnych. Wielkość ta podlega zatem rozkładowi &amp;lt;math&amp;gt;\chi^2&amp;lt;/math&amp;gt; o dwóch stopniach swobody.&lt;br /&gt;
Możemy oszacować względny błąd &amp;lt;math&amp;gt;P(f_1) &amp;lt;/math&amp;gt; dla danej częstości &amp;lt;math&amp;gt;f_1&amp;lt;/math&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\epsilon_r= \sigma_{P_{f_1}}/\mu_{P_{f_1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dla rozkładu &amp;lt;math&amp;gt;\chi_2^2&amp;lt;/math&amp;gt;:  &amp;lt;math&amp;gt;\sigma^2 = 2n&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;\mu = n&amp;lt;/math&amp;gt;, gdzie &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; jest ilością stopni swobody. W naszym przypadku &amp;lt;math&amp;gt;n =2&amp;lt;/math&amp;gt; więc mamy &amp;lt;math&amp;gt;\epsilon_f = 1&amp;lt;/math&amp;gt;, co oznacza, że dla pojedynczego binu częstości w widmie &amp;lt;math&amp;gt;P(f)&amp;lt;/math&amp;gt; względny błąd wynosi 100%. &lt;br /&gt;
&lt;br /&gt;
Aby zmniejszyć ten błąd trzeba zwiększyć ilość stopni swobody. Są generalnie stosowane dwie techniki. Pierwsza to uśrednianie sąsiednich binów częstości. Otrzymujemy wówczas wygładzony estymator mocy &amp;lt;math&amp;gt;\hat{P}_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\hat{P}_k = \frac{1}{l}[P_k + P_{k+1} + \dots + P_{k+l-1}]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zakładając, że biny częstości  &amp;lt;math&amp;gt;P_i&amp;lt;/math&amp;gt; są niezależne estymator &amp;lt;math&amp;gt;P_k&amp;lt;/math&amp;gt; ma rozkład &amp;lt;math&amp;gt;\chi^2&amp;lt;/math&amp;gt; o ilości stopni swobody równej &amp;lt;math&amp;gt;n= 2l&amp;lt;/math&amp;gt;. Względny błąd takiego estymatora to: &amp;lt;math&amp;gt;\epsilon_r= \sqrt{\frac{1}{l}}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Innym sposobem poprawy estymatora mocy jest podzielenie sygnału na fragmenty, obliczenie periodogramu dla każdego fragmentu, a następnie zsumowanie otrzymanych wartości:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\hat{P}_k=[P_{k,1}+P_{k,2}+\dots+P_{k,j}+\dots+P_{k,q}]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;S_{k,j}&amp;lt;/math&amp;gt; jest estymatą składowej o częstości &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; w oparciu o &amp;lt;math&amp;gt;j-ty&amp;lt;/math&amp;gt; fragment sygnału. Ilość stopni swobody wynosi w tym przypadku &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; zatem względny błąd wynosi: &amp;lt;math&amp;gt;\epsilon_r = \sqrt{\frac{1}{q}}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Zauważmy, że w obu metodach zmniejszamy wariancję estymatora kosztem rozdzielczości w częstości.&lt;br /&gt;
&lt;br /&gt;
===Metoda Welcha===&lt;br /&gt;
Proszę napisać i przetestować funkcję implementującą metodę Welcha estymacji widma mocy. Algorytm Welcha:&lt;br /&gt;
# sygnał &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; o długości ''N'' jest dzielony na segmenty, każdy o długości &amp;lt;math&amp;gt;N_s&amp;lt;/math&amp;gt;. Odcinki mogą na siebie zachodzić na &amp;lt;math&amp;gt;N_z&amp;lt;/math&amp;gt; punktów. Czyli są względem siebie przesunięte o &amp;lt;math&amp;gt;N_p = N_s-N_z&amp;lt;/math&amp;gt;.&lt;br /&gt;
# z każdego segmentu liczony jest okienkowany periodogram&lt;br /&gt;
# periodogramy są sumowane&lt;br /&gt;
# wynik dzielony jest przez efektywne wykorzystanie każdego kawałka sygnału w estymacie: &amp;lt;tt&amp;gt;K_eff = dlogosc_okna * ilosc_okien / dlugosc_sygnalu&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funkcję proszę przetestować obliczając dla funkcji sinus energię sygnału w dziedzinie czasu i w dziedzinie częstości. Testy proszę wykonać dla okna prostokątnego, Blackmana i Haminga. &lt;br /&gt;
&lt;br /&gt;
 * &amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
def pwelch(s,okienko, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okienko)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,F_samp)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Całość razem z kodem testującym:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , Fs):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    Fs- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
def pwelch(s,okienko, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okienko)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,Fs)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 3.1, T =20, Fs = F_samp, phi = 0)&lt;br /&gt;
N = len(x) # dłogość sygnału&lt;br /&gt;
&lt;br /&gt;
okno = np.ones(N)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N)&lt;br /&gt;
#okno = np.hamming(N)&lt;br /&gt;
&lt;br /&gt;
s = x*okno # sygnał okienkowany&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
(P, F) = periodogram(x,okno,F_samp)&lt;br /&gt;
py.plot(F,P) &lt;br /&gt;
py.title('periodogram'+' energia: '+ str(np.sum(P)))&lt;br /&gt;
&lt;br /&gt;
#periodogram&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
N_s = N/8&lt;br /&gt;
#okno = np.ones(N_s)#/np.sqrt(N)&lt;br /&gt;
#okno = np.blackman(N_s)&lt;br /&gt;
okno = np.hamming(N_s)&lt;br /&gt;
&lt;br /&gt;
         &lt;br /&gt;
(P, F) = pwelch(x,okno,N_s/10,F_samp)&lt;br /&gt;
py.plot(F,P)&lt;br /&gt;
py.title('periodogram Welcha'+' energia: '+ str(np.sum(P)))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Porównanie rozdzielczości i wariancji w periodogramie i w estymatorze Welcha===&lt;br /&gt;
#  wygeneruj 100 realizacji sygnału będącego sumą sinusoidy (f=20Hz, T=10s, Fs =100Hz) i szumu gaussowskiego&lt;br /&gt;
# dla każdej realizacji oblicz widmo mocy za pomocą periodogramu okienkowanego oknem Blackmana&lt;br /&gt;
# wykreśl wszystkie otrzymane widma na wspólnym wykresie (subplot(2,1,1))&lt;br /&gt;
# Powtórz krok 2) dla estymatora Welcha z oknem Blackmana o długości 1/10 długości sygnału przesuwanym co 2 punkty, otrzymane widma wykreśl  na wspólnym wykresie (subplot(2,1,2))&lt;br /&gt;
&lt;br /&gt;
* Co można powiedzieć o rozdzielczości i względnym błędzie obu metod?&lt;br /&gt;
&amp;lt;tt&amp;gt;bl_wzg = np.std(S,axis = 0)/np.mean(S,axis = 0)&amp;lt;/tt&amp;gt; gdzie S jest tablicą zawierającą widma dla każdej z realizacji.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
&lt;br /&gt;
def periodogram(s, okno , Fs):&lt;br /&gt;
    '''peiodogram sygnału s&lt;br /&gt;
    okno - synał będzie przez nie przemnożony w czasie&lt;br /&gt;
    Fs- częstość próbkowania'''&lt;br /&gt;
&lt;br /&gt;
    s = s*okno&lt;br /&gt;
    N_fft = len(s)&lt;br /&gt;
    S = fft(s,N_fft)#/np.sqrt(N_fft)&lt;br /&gt;
    P = S*S.conj()/np.sum(okno**2)&lt;br /&gt;
    &lt;br /&gt;
    P = P.real # P i tak ma zerowe wartośći urojone, ale trzeba ykonać konwersję typów&lt;br /&gt;
    F = fftfreq(N_fft, 1/Fs)&lt;br /&gt;
    return (fftshift(P),fftshift(F))&lt;br /&gt;
def pwelch(s,okno, przesuniencie, Fs):&lt;br /&gt;
    '''s - sygnał&lt;br /&gt;
    okienko - przebieg czasowy okienka &lt;br /&gt;
    przesuniecie - o ile punktów okienka są przesówane względem siebie&lt;br /&gt;
    Fs - częstość próbkowania'''&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    N_s = len(okno)&lt;br /&gt;
    &lt;br /&gt;
    start_fragmentow = np.arange(0,N-N_s+1,przesuniencie)&lt;br /&gt;
    ile_fragmentow = len(start_fragmentow)&lt;br /&gt;
    ile_przekrycia = N_s*ile_fragmentow/float(N)&lt;br /&gt;
    P_sredni = np.zeros(N_s)&lt;br /&gt;
    for i in range(ile_fragmentow):&lt;br /&gt;
        s_fragment = s[start_fragmentow[i]:start_fragmentow[i]+N_s]&lt;br /&gt;
        (P, F) = periodogram(s_fragment,okno,Fs)&lt;br /&gt;
        P_sredni += P&lt;br /&gt;
    return (P_sredni/ile_przekrycia,F)&lt;br /&gt;
&lt;br /&gt;
def realizacja(T,Fs):&lt;br /&gt;
    (x,t) = sin(f = 20.0, T = T, Fs = Fs, phi = 0)&lt;br /&gt;
    x += 2*np.random.randn(len(x))&lt;br /&gt;
    return x&lt;br /&gt;
&lt;br /&gt;
T=10.0&lt;br /&gt;
Fs = 100.0&lt;br /&gt;
N = T*Fs&lt;br /&gt;
Nw = N/10.0&lt;br /&gt;
okno = np.blackman(N)&lt;br /&gt;
okno_welch = np.blackman(Nw)&lt;br /&gt;
&lt;br /&gt;
N_rep = 100&lt;br /&gt;
S_perio = np.zeros((N_rep,N))&lt;br /&gt;
S_welch = np.zeros((N_rep,Nw))&lt;br /&gt;
py.figure(1)&lt;br /&gt;
for i in range(N_rep):&lt;br /&gt;
    s = realizacja(T,Fs)&lt;br /&gt;
    (P, F) = periodogram(s,okno,Fs) &lt;br /&gt;
    S_perio[i] = P&lt;br /&gt;
    py.subplot(2,1,1)&lt;br /&gt;
    py.plot(F,P) &lt;br /&gt;
    (P, F) = pwelch(s,okno_welch,Nw/10,Fs)&lt;br /&gt;
    S_welch[i] = P&lt;br /&gt;
    py.subplot(2,1,2)&lt;br /&gt;
    py.plot(F,P)&lt;br /&gt;
&lt;br /&gt;
py.figure(2)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(np.std(S_perio,axis = 0)/np.mean(S_perio,axis = 0))&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.std(S_welch,axis = 0)/np.mean(S_welch,axis = 0))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Wielookienkowa metoda Thomsona===&lt;br /&gt;
Metoda ta &lt;br /&gt;
[http://ieeexplore.ieee.org/Xplore/login.jsp?url=http%3A%2F%2Fieeexplore.ieee.org%2Fiel5%2F5%2F31317%2F01456701.pdf%3Farnumber%3D1456701&amp;amp;authDecision=-201 Spectrum estimation and harmonic analysis] &lt;br /&gt;
znana jest pod anglojęzyczną nazwą  ''multitaper''. &lt;br /&gt;
&lt;br /&gt;
Można ją opisać poniższym algorytmem:&lt;br /&gt;
* wygeneruj sekwencję ortogonalnych okienek charakteryzujących się minimalnymi wyciekami widma (stosunek energii w piku centralnym do energii w listkach bocznych jest wysoki). Sekwencja takich okien nazywana jest discrete prolate spheroidal sequences (DPSS) lub sekwencją Slepiana.&lt;br /&gt;
* oblicz widmo sygnału okienkowanego każdym z okien w sekwencji&lt;br /&gt;
* uśrednij otrzymane widma&lt;br /&gt;
&lt;br /&gt;
Kolejne dwa zadania służą zapoznaniu się z tą metodą.&lt;br /&gt;
====Własności okienek DPSS ====&lt;br /&gt;
Do generacji sekwencji okienek DPSS wykorzystamy moduł [http://brain.fuw.edu.pl/edu-wiki/images/f/f6/Gendpss.py Gendpss.py]. Proszę go zapisać w swoim katalogu roboczym. &lt;br /&gt;
Importujemy go do naszych programów tak jak każdy inny moduł np.:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import Gendpss as dpss&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Funkcja potrzebna nam z tego modułu to &amp;lt;tt&amp;gt;gendpss()&amp;lt;/tt&amp;gt;. Funkcja ta wytwarza obiekt reprezentujący konkretną sekwencję DPSS. Wywołujemy ją następująco:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
w = dpss.gendpss(N,NW,K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:gdzie: N: długość okna,&lt;br /&gt;
:        NW: iloczyn czas-szerokość pasma&lt;br /&gt;
:        K: ile okien w sekwencji&lt;br /&gt;
Po powyższym wywołaniu obiekt &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; posiada dwie interesujące nas tablice:&lt;br /&gt;
* &amp;lt;tt&amp;gt;w.lambdas&amp;lt;/tt&amp;gt; - to wartości własne okienek. Są one miarą koncentracji energii w piku głównym, jest to zatem miara jakości okienka (dobre okienka mają wartości własne bliskie 1). Zgodnie z teorią takich wartości powinno być 2*NW-1.&lt;br /&gt;
* &amp;lt;tt&amp;gt;w.dpssarray[i]&amp;lt;/tt&amp;gt; - i-te okienko.&lt;br /&gt;
&lt;br /&gt;
=====Polecenia:=====&lt;br /&gt;
Proszę:&lt;br /&gt;
* wygenerować okienka o długości 256, NW = 2. Ilość okien K raz ustalić na 3 (2*NW-1) a drugi raz na 5. Dla ilu okienek ich wartości własne są bliskie 1?&lt;br /&gt;
* narysować przebieg czasowy okienek&lt;br /&gt;
* sprawdzić czy energia okienek jest znormalizowana do 1.&lt;br /&gt;
* sprawdzić czy kolejne okienka są do siebie ortogonalne. W tym celu należy obliczyć iloczyn skalarny pomiędzy kolejnymi okienkami (np.sum(w.dpssarray[i]*w.dpssarray[j])). &lt;br /&gt;
* wywrysować widma okienek analogicznie jak [[%C4%86wiczenia_3#Badanie_w.C5.82asno.C5.9Bci_okien|w tym ćwiczeniu]]&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import gendpss as dpss&lt;br /&gt;
from numpy.fft import fft,fftshift,fftfreq&lt;br /&gt;
&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1.0/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NW = 2&lt;br /&gt;
ile_okien = 5#2*NW-1&lt;br /&gt;
N_okna = 256&lt;br /&gt;
w = dpss.gendpss(N=N_okna,NW=NW,K=ile_okien)&lt;br /&gt;
print 'Wartości własne:'&lt;br /&gt;
print w.lambdas&lt;br /&gt;
&lt;br /&gt;
print 'Wartości iloczynów skalarnych pomiędzy kolejnymi okienekami:'&lt;br /&gt;
py.figure(1)&lt;br /&gt;
for i in range(ile_okien):&lt;br /&gt;
    py.plot(w.dpssarray[i])&lt;br /&gt;
    for j in range(i+1):&lt;br /&gt;
        print np.sum(w.dpssarray[i]*w.dpssarray[j]),&lt;br /&gt;
    print&lt;br /&gt;
&lt;br /&gt;
py.figure(2)&lt;br /&gt;
NFFT = N_okna*4&lt;br /&gt;
S=np.zeros((ile_okien,NFFT))&lt;br /&gt;
for i in range(ile_okien):&lt;br /&gt;
    py.subplot(ile_okien,1,i+1)&lt;br /&gt;
    (S_db, F)= widmo_dB(w.dpssarray[i], NFFT, 1.0)&lt;br /&gt;
    S[i,:]=S_db&lt;br /&gt;
    py.plot(F,S_db)&lt;br /&gt;
    py.ylim((-200,20))&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Estymacja widma mocy metodą multitaper ====&lt;br /&gt;
Proszę napisać funkcję do estymacji mocy metodą multitaper.&lt;br /&gt;
Funkcja powinna pobierać następujące argumenty: sygnał, iloczyn NW, częstość próbkowania sygnału. Funkcja powinna zwracać krotkę &amp;lt;tt&amp;gt;(S,F)&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;S&amp;lt;/tt&amp;gt; widmo mocy, &amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt; skala częstości.&lt;br /&gt;
Przykładowe wywołanie takiej funkcji powinno wyglądać tak:&lt;br /&gt;
&amp;lt;tt&amp;gt; (S,F) = mtm(s,  NW = 3, Fs = 128)&amp;lt;/tt&amp;gt;&lt;br /&gt;
Algorytm do zastosowania wewnątrz funkcji:&lt;br /&gt;
# Oblicz maksymalną liczbę okienek &amp;lt;tt&amp;gt; K = 2*NW-1&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Oblicz długość sygnału&lt;br /&gt;
# wygeneruj serię okienek dpss&lt;br /&gt;
# dla każdego z otrzymanych okienek oblicz widmo mocy iloczynu tego okienka i sygnału. Dla i-tego okienka będzie to: &amp;lt;tt&amp;gt;Si = np.abs(fft(s*w.dpssarray[i]))**2&amp;lt;/tt&amp;gt;&lt;br /&gt;
# uśrednij widma otrzymane dla wszystkich okienek&lt;br /&gt;
# wygeneruj oś częstości (&amp;lt;tt&amp;gt;fftfreq&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Działanie funkcji sprawdź estymując i wykreślając widmo sinusoidy np. o częstości 10 Hz, czasie trwania 1s, próbkowanej 100Hz z dodanym szumem gaussowskim o średniej 0 i wariancji 1. Sprawdź także zachowanie energii przez tą estymatę. Dla porównania na tym samym wykresie dorysuj widmo otrzymane przez [[Nieparametryczne_widmo_mocy#Okienkowanie_a_widmo_mocy:_periodogram|periodogram]] z oknem prostokątnym.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import gendpss as dpss&lt;br /&gt;
from numpy.fft import fft,fftshift,fftfreq&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def mtm(s, NW = 3, Fs = 128):&lt;br /&gt;
    '''estymacja widma w oparciu o  metodę Multiteper &lt;br /&gt;
    D. J. Thomson, “Spectrum Estimation and Harmonic Analysis,” Proceedings of the&lt;br /&gt;
    IEEE, vol. 70, no. 9, pp. 1055 – 1096, 1982.&lt;br /&gt;
    x - sygnał&lt;br /&gt;
    N -ilość punktów okna&lt;br /&gt;
    NW - iloczyn długości okna w czasie i szerokości w częstości&lt;br /&gt;
    K - ilość okien&lt;br /&gt;
&lt;br /&gt;
    funkcja zwraca estymatę mocy widmowej&lt;br /&gt;
    '''&lt;br /&gt;
    K = 2*NW-1&lt;br /&gt;
    N = len(s)&lt;br /&gt;
    w = dpss.gendpss(N,NW,K)&lt;br /&gt;
    S=np.zeros(N)&lt;br /&gt;
    for i in range(K):&lt;br /&gt;
        Si = np.abs(fft(s*w.dpssarray[i]))**2&lt;br /&gt;
        S[:] += Si.real&lt;br /&gt;
    S = S/K&lt;br /&gt;
    F = fftfreq(N,1.0/Fs)&lt;br /&gt;
    return (fftshift(S),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fs = 100.0&lt;br /&gt;
NW = 3&lt;br /&gt;
(s,t) = sin(f=10.2,Fs=Fs)&lt;br /&gt;
s = s+np.random.randn(len(s))&lt;br /&gt;
(S,F) = mtm(s, NW = NW,  Fs = Fs)&lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.plot( F,fftshift(np.abs(fft(s))**2/len(s) ) ,'g')&lt;br /&gt;
&lt;br /&gt;
print np.sum(S)&lt;br /&gt;
print np.sum(s**2)&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_3&amp;diff=4246</id>
		<title>Ćwiczenia 3</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_3&amp;diff=4246"/>
		<updated>2015-10-05T10:16:59Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Badanie własności okien */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Twierdzenie o splocie ==&lt;br /&gt;
Na pierwszych ćwiczeniach poznaliśmy poznaliśmy operację [[Systemy_liniowe_niezmiennicze_w_czasie#Splot|splotu]] jako efekt działania systemu liniowego niezmienniczego w czasie. Poznaliśmy wówczas jego [[Systemy_liniowe_niezmiennicze_w_czasie#W.C5.82asno.C5.9Bci_splotu|własności]].&lt;br /&gt;
Okazuje się, że gdy rozważamy sprzężone ze sobą za pomocą transformaty Fouriera dziedziny czasu i częstości splot ma wiele wspólnego z mnożeniem. Związek ten można zapisać jako &lt;br /&gt;
[[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|Twierdzenie o splocie:]] &lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid2&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
g(t)=\left(s * h\right)(t)\quad \Rightarrow \quad G(f)=S(f)\cdot H(f)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
To twierdzenie działa też w drugą stronę:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
G(f)=\left(S * H\right)(f)\quad \Rightarrow \quad g(t)=s(t)\cdot h(t)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W praktyce oznacza to tyle, że jeśli w jednej dziedzinie jakieś dwa sygnały przez siebie przemnożymy, to w drugiej dziedzinie transformaty tych sygnałów splatają się. Własność ta ma bardzo ważne konsekwencje, np. przy estymacji widma skończonego fragmentu sygnału. Dlaczego?&lt;br /&gt;
&lt;br /&gt;
Wyobraźmy sobie, że mamy nieskończenie długi sygnał. Oprócz niego mamy też funkcję, która jest niezerowa tylko na skończonym odcinku. Funkcję taką będziemy nazywać oknem. Pobranie fragmentu sygnału można wyobrazić sobie jako efekt pomnożenia badanego sygnału przez okno. Ta operacja mnożenia w dziedzinie czasu, w dziedzinie częstości odpowiada splotowi widma sygnału z widmem okna. Aby uzyskać sygnał o skończonej długości odrzucamy wyzerowane odcinki. FFT widzi taki skończony odcinek jako  [[%C4%86wiczenia_2#Przed.C5.82u.C5.BCenie_przez_periodyczn.C4.85_replikacj.C4.99|periodyczne przedłużenie]].  Widać, że w praktyce estymowania widma zawsze mamy  do czynienia z widmami będącymi splotem widma sygnału i widma okna, ponieważ zawsze pracujemy z sygnałami o skończonej długości.&lt;br /&gt;
&lt;br /&gt;
===Zastosowania===&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	zamiana splotu na mnożenie&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	daje wgląd w okienkowanie&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	łatwo zrozumieć działanie filtrów&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Okienka==&lt;br /&gt;
===Wstęp===&lt;br /&gt;
* Jakie są dostępne okna w &amp;lt;tt&amp;gt;scipy.signal&amp;lt;/tt&amp;gt;? Proszę odwiedzić stronę z [http://docs.scipy.org/doc/scipy-0.14.0/reference/signal.html dokumentacją].&lt;br /&gt;
* Jak wyglądają te okienka?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
from scipy import signal&lt;br /&gt;
w = signal.bartlett(10)&lt;br /&gt;
print(w)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Badanie własności okien===&lt;br /&gt;
&lt;br /&gt;
* Wykreśl okienko Bartletta o długości 100 i 101 próbek.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as py&lt;br /&gt;
&lt;br /&gt;
window = np.bartlett(101)&lt;br /&gt;
py.plot(window)&lt;br /&gt;
py.title(&amp;quot;okno Bartletta&amp;quot;)&lt;br /&gt;
py.ylabel(&amp;quot;Amplituda&amp;quot;)&lt;br /&gt;
py.xlabel(u&amp;quot;próbki&amp;quot;)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Proszę wykreślić widmo amplitudowe okna Bartletta o długości 101 próbek w skali [[wikipl:Decybel|dB]] (&amp;lt;tt&amp;gt;20*np.log10(.)&amp;lt;/tt&amp;gt;), raz korzystając z fft o naturalnej długości okna &amp;lt;tt&amp;gt;W = fft(okno)&amp;lt;/tt&amp;gt;, a drugi raz korzystając z przedłużenia zerami (w tym przypadku dostaniemy interpolowaną wersję widma) &amp;lt;tt&amp;gt;W = fft(okno, 2048)&amp;lt;/tt&amp;gt;. Proszę zwrócić uwagę na charakterystyczne elementy: szerokość piku głównego, szybkość zanikania listków bocznych, zera. &lt;br /&gt;
&lt;br /&gt;
Przydatna może być tu funkcja do obliczania widma (proszę przeanalizować kod i w razie wątpliwości poprosić o objaśnienie):&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
&lt;br /&gt;
def widmo_dB(s, N_fft, F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1.0/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 *&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import fft, fftshift&lt;br /&gt;
import matplotlib.pyplot as py&lt;br /&gt;
&lt;br /&gt;
window = np.bartlett(51)&lt;br /&gt;
&lt;br /&gt;
W = fft(window)/len(window)&lt;br /&gt;
# rysować będziemy w skali logarytmicznej&lt;br /&gt;
widmo = abs(fftshift(W))&lt;br /&gt;
widmo_dB = 20*np.log10(widmo)&lt;br /&gt;
f = np.linspace(-0.5,0.5,len(W))&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(f,widmo_dB)&lt;br /&gt;
py.axis('tight')&lt;br /&gt;
&lt;br /&gt;
W_zeropadded = fft(window, 2048) / len(window)&lt;br /&gt;
widmo_zeropadded = abs(fftshift(W_zeropadded))&lt;br /&gt;
f = np.linspace(-0.5,0.5,len(W_zeropadded))&lt;br /&gt;
widmo_dB_zeropadded = 20*np.log10(widmo_zeropadded)&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(f ,widmo_dB_zeropadded)&lt;br /&gt;
py.title(&amp;quot;widmo okna Bartletta&amp;quot;)&lt;br /&gt;
py.ylabel(u&amp;quot;Wartość [dB]&amp;quot;)&lt;br /&gt;
py.xlabel(u&amp;quot;znormalizowana częstość&amp;quot;)&lt;br /&gt;
py.axis('tight')&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* A jakie własności ma okno prostokątne? Najprościej można je zrobić tak: &amp;lt;tt&amp;gt;window = np.ones(N)&amp;lt;/tt&amp;gt;. Proszę wykonać analogiczne rysunki jak dla okna Bartletta.&lt;br /&gt;
&lt;br /&gt;
* Proszę porównać przebiegi czasowe i własności widmowe pozostałych okien dostępnych w &amp;lt;tt&amp;gt;scipy.signal&amp;lt;/tt&amp;gt;, m.in.: &lt;br /&gt;
**blackman(M) 	&lt;br /&gt;
**hamming(M) 	&lt;br /&gt;
**hanning(M) 	&lt;br /&gt;
**kaiser(M, beta)&lt;br /&gt;
&lt;br /&gt;
===Własności okien w działaniu===&lt;br /&gt;
==== Okienko i szerokość prążka w widmie ====&lt;br /&gt;
* Wygeneruj sinusoidę o częstości &amp;lt;math&amp;gt;f=10.2&amp;lt;/math&amp;gt; Hz fazie 0, czasie trwania &amp;lt;math&amp;gt;T=1&amp;lt;/math&amp;gt; s, i częstości próbkowania &amp;lt;math&amp;gt;Fs=100&amp;lt;/math&amp;gt; Hz&lt;br /&gt;
* Wygeneruj okno prostokątne o długości równej długości sinusoidy.&lt;br /&gt;
* Zokienkuj sygnał mnożąc sinusoidę przez okienko&lt;br /&gt;
* Wykreśl zokienkowany sygnał, widmo zokienkowanego sygnału, widmo okienka&lt;br /&gt;
* Powtórz powyższe kroki dla okienek Bartletta, Hanna, Hamminga i Blackmana. Przy wykreślaniu widma zokienkowanego sygnału ustal zakres osi pionowej na [-50 10] (zastosuj &amp;lt;tt&amp;gt;py.ylim((-50,10)&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
* Proszę porównać widma otrzymane dla poszczególnych typów okienek.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 10.2, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,1)&lt;br /&gt;
okno = np.ones(len(x))/np.sqrt(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany prostokątem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,2)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego prostokątem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,3)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo prostokąta')&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,4)&lt;br /&gt;
okno = np.blackman(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Blackmanem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,5)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Blackmanem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,6)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Blackmana')&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,7)&lt;br /&gt;
okno = np.hamming(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Hamming')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,8)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Hamming')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,9)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Hamming')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
====Wpływ okienkowania na wykrywalność składowych o różnej amplitudzie ====&lt;br /&gt;
* Wygeneruj sygnał będący sumą dwóch sinusoid o fazie 0, czasie trwania &amp;lt;math&amp;gt;T=1&amp;lt;/math&amp;gt; s, i częstości próbkowania &amp;lt;math&amp;gt;Fs=100&amp;lt;/math&amp;gt; Hz. Jedna niech ma częstość &amp;lt;math&amp;gt;f=10.2&amp;lt;/math&amp;gt; Hz. Częstość drugiej, w kolejnych zapuszczeniach skryptu proszę zmieniać od 11,4 do 16,4 Hz z krokiem co 0,5 Hz.&lt;br /&gt;
* Jaki jest wpływ okienek na możliwości rozróżnienia dwóch częstości?&lt;br /&gt;
* Proszę powtórzyć iteracje dla przypadku gdy druga z sinusoid ma 10-krotnie niższą amplitudę.&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source  lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x1,t) = sin(f = 10.2, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
&lt;br /&gt;
(x2,t) = sin(f = 11.4+0.5*1, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
x = x1 + 1*x2 #0.1*&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,1)&lt;br /&gt;
okno = np.ones(len(x))/np.sqrt(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany prostokątem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,2)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego prostokątem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,3)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo prostokąta')&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,4)&lt;br /&gt;
okno = np.blackman(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Blackmanem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,5)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Blackmanem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,6)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Blackmana')&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,7)&lt;br /&gt;
okno = np.hamming(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Hamming')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,8)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Hamming')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,9)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Hamming')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Okienkować możemy też w częstości===&lt;br /&gt;
&lt;br /&gt;
* Proszę wykreślić widmo, a następie obliczyć i wykreślić [[%C4%86wiczenia_2#Transformaty_rzeczywiste_i_Hermitowskie|odwrotną transformatę Fouriera dla sygnału rzeczywistego]] zadanego w dziedzinie częstości przez (poniższy kod definiuje sygnał w dodatniej części widma):&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
S = np.zeros(128)&lt;br /&gt;
S[21] = 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Proszę wykreślić okienko prostokątne w częstości, pozycja 1 w binach częstości od 21 do 30, a następnie wykreślić odpowiadający mu sygnał w dziedzinie czasu.&lt;br /&gt;
&lt;br /&gt;
* Koncepcyjnie najprostszym filtrem jest operacja przemnożenia widma sygnału przez okienko w dziedzinie częstości a następnie zastosowanie odwrotnej transformaty Fouriera. Co stanie się z sygnałem w dziedzinie czasu, a co w dziedzinie częstości, jeśli chcielibyśmy przefiltrować go pasmowo przy użyciu filtra pasmowo przepustowego z poprzedniego punktu?&lt;br /&gt;
 * &amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  irfft,fftshift&lt;br /&gt;
 &lt;br /&gt;
S= np.zeros(128)&lt;br /&gt;
S[21:28] = 1&lt;br /&gt;
&lt;br /&gt;
s = fftshift(irfft(S))&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
F = range(len(S))&lt;br /&gt;
py.stem(F,S)&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
t = range(len(s))&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Porównajmy działanie najprostszych filtrów fft na biały szum.&lt;br /&gt;
** Proszę wytworzyć sygnał będący białym szumem o długości 256 próbek.&lt;br /&gt;
** Policz transformatę rzeczywistą tego sygnału.&lt;br /&gt;
** Przygotuj dwa okna w dziedzinie częstości (w części dodatniej)  o długości 129: &lt;br /&gt;
*** okno prostokątne  z jedynkami w punktach 20:30&lt;br /&gt;
*** okno Gaussowskie &amp;lt;tt&amp;gt;np.exp(-((F-25.0)/5)**2)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Przemnóż widmo sygnału przez każde z okien i oblicz odwrotną transformatę Fouriera. &lt;br /&gt;
** Zilustruj wyniki rysunkiem opisanym przez poniższą tabelkę:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|border = 1&lt;br /&gt;
|okno prostokątne w częstości &lt;br /&gt;
| okno Gaussowskie w częstości&lt;br /&gt;
|-&lt;br /&gt;
|przebieg czasowy odwrotnej tr. Fouriera okna Prostokątnego &lt;br /&gt;
|przebieg czasowy odwrotnej tr. Fouriera okna Gaussowskiego&lt;br /&gt;
|-&lt;br /&gt;
|przebieg czasowy szumu&lt;br /&gt;
|przebieg czasowy szumu&lt;br /&gt;
|-&lt;br /&gt;
|Przebieg czasowy odwrotnej tr. Fouriera iloczynu widma szumu i okna prostokątnego&lt;br /&gt;
|Przebieg czasowy odwrotnej tr. Fouriera iloczynu widma szumu i okna Gaussowskiego&lt;br /&gt;
|}&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  irfft,rfft,fftshift&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
szum = np.random.randn(128*2-2)&lt;br /&gt;
SZum = rfft(szum)&lt;br /&gt;
&lt;br /&gt;
S_prost= np.zeros(128)&lt;br /&gt;
S_prost[20:30]=1&lt;br /&gt;
s_prost = fftshift(irfft(S_prost))&lt;br /&gt;
&lt;br /&gt;
t = np.arange(len(s_prost))&lt;br /&gt;
F = np.arange(len(S_prost))&lt;br /&gt;
S_gauss = np.exp(-((F-25.0)/5)**2)&lt;br /&gt;
s_gauss = fftshift(irfft(S_gauss))&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,1)&lt;br /&gt;
py.stem(F,S_prost)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,3)&lt;br /&gt;
py.plot(t,s_prost)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,5)&lt;br /&gt;
py.plot(t,szum)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,7)&lt;br /&gt;
filtrowanySygnal = fftshift(irfft(SZum*S_prost))&lt;br /&gt;
py.plot(filtrowanySygnal)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,2)&lt;br /&gt;
py.stem(F,S_gauss)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,4)&lt;br /&gt;
py.plot(t,s_gauss)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,6)&lt;br /&gt;
py.plot(t,szum)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,8)&lt;br /&gt;
filtrowanySignal = fftshift(irfft(SZum*S_gauss))&lt;br /&gt;
py.plot(filtrowanySignal)&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_3&amp;diff=4245</id>
		<title>Ćwiczenia 3</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_3&amp;diff=4245"/>
		<updated>2015-10-05T10:16:21Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Wstęp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Twierdzenie o splocie ==&lt;br /&gt;
Na pierwszych ćwiczeniach poznaliśmy poznaliśmy operację [[Systemy_liniowe_niezmiennicze_w_czasie#Splot|splotu]] jako efekt działania systemu liniowego niezmienniczego w czasie. Poznaliśmy wówczas jego [[Systemy_liniowe_niezmiennicze_w_czasie#W.C5.82asno.C5.9Bci_splotu|własności]].&lt;br /&gt;
Okazuje się, że gdy rozważamy sprzężone ze sobą za pomocą transformaty Fouriera dziedziny czasu i częstości splot ma wiele wspólnego z mnożeniem. Związek ten można zapisać jako &lt;br /&gt;
[[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|Twierdzenie o splocie:]] &lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid2&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
g(t)=\left(s * h\right)(t)\quad \Rightarrow \quad G(f)=S(f)\cdot H(f)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
To twierdzenie działa też w drugą stronę:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
G(f)=\left(S * H\right)(f)\quad \Rightarrow \quad g(t)=s(t)\cdot h(t)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W praktyce oznacza to tyle, że jeśli w jednej dziedzinie jakieś dwa sygnały przez siebie przemnożymy, to w drugiej dziedzinie transformaty tych sygnałów splatają się. Własność ta ma bardzo ważne konsekwencje, np. przy estymacji widma skończonego fragmentu sygnału. Dlaczego?&lt;br /&gt;
&lt;br /&gt;
Wyobraźmy sobie, że mamy nieskończenie długi sygnał. Oprócz niego mamy też funkcję, która jest niezerowa tylko na skończonym odcinku. Funkcję taką będziemy nazywać oknem. Pobranie fragmentu sygnału można wyobrazić sobie jako efekt pomnożenia badanego sygnału przez okno. Ta operacja mnożenia w dziedzinie czasu, w dziedzinie częstości odpowiada splotowi widma sygnału z widmem okna. Aby uzyskać sygnał o skończonej długości odrzucamy wyzerowane odcinki. FFT widzi taki skończony odcinek jako  [[%C4%86wiczenia_2#Przed.C5.82u.C5.BCenie_przez_periodyczn.C4.85_replikacj.C4.99|periodyczne przedłużenie]].  Widać, że w praktyce estymowania widma zawsze mamy  do czynienia z widmami będącymi splotem widma sygnału i widma okna, ponieważ zawsze pracujemy z sygnałami o skończonej długości.&lt;br /&gt;
&lt;br /&gt;
===Zastosowania===&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	zamiana splotu na mnożenie&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	daje wgląd w okienkowanie&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	łatwo zrozumieć działanie filtrów&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Okienka==&lt;br /&gt;
===Wstęp===&lt;br /&gt;
* Jakie są dostępne okna w &amp;lt;tt&amp;gt;scipy.signal&amp;lt;/tt&amp;gt;? Proszę odwiedzić stronę z [http://docs.scipy.org/doc/scipy-0.14.0/reference/signal.html dokumentacją].&lt;br /&gt;
* Jak wyglądają te okienka?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
from scipy import signal&lt;br /&gt;
w = signal.bartlett(10)&lt;br /&gt;
print(w)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Badanie własności okien===&lt;br /&gt;
&lt;br /&gt;
* Wykreśl okienko Bartletta o długości 100 i 101 próbek.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as py&lt;br /&gt;
&lt;br /&gt;
window = np.bartlett(101)&lt;br /&gt;
py.plot(window)&lt;br /&gt;
py.title(&amp;quot;okno Bartletta&amp;quot;)&lt;br /&gt;
py.ylabel(&amp;quot;Amplituda&amp;quot;)&lt;br /&gt;
py.xlabel(u&amp;quot;próbki&amp;quot;)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Proszę wykreślić widmo amplitudowe okna Bartletta o długości 101 próbek w skali [[wikipl:Decybel|dB]] (&amp;lt;tt&amp;gt;20*np.log10(.)&amp;lt;/tt&amp;gt;), raz korzystając z fft o naturalnej długości okna &amp;lt;tt&amp;gt;W = fft(okno)&amp;lt;/tt&amp;gt;, a drugi raz korzystając z przedłużenia zerami (w tym przypadku dostaniemy interpolowaną wersję widma) &amp;lt;tt&amp;gt;W = fft(okno, 2048)&amp;lt;/tt&amp;gt;. Proszę zwrócić uwagę na charakterystyczne elementy: szerokość piku głównego, szybkość zanikania listków bocznych, zera. &lt;br /&gt;
&lt;br /&gt;
Przydatna może być tu funkcja do obliczania widma (proszę przeanalizować kod i w razie wątpliwości poprosić o objaśnienie):&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
&lt;br /&gt;
def widmo_dB(s, N_fft, F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1.0/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 *&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import fft, fftshift&lt;br /&gt;
import matplotlib.pyplot as py&lt;br /&gt;
&lt;br /&gt;
window = np.bartlett(51)&lt;br /&gt;
&lt;br /&gt;
W = fft(window)/len(window)&lt;br /&gt;
# rysować będziemy w skali logarytmicznej&lt;br /&gt;
widmo = abs(fftshift(W))&lt;br /&gt;
widmo_dB = 20*np.log10(widmo)&lt;br /&gt;
f = np.linspace(-0.5,0.5,len(W))&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(f,widmo_dB)&lt;br /&gt;
py.axis('tight')&lt;br /&gt;
&lt;br /&gt;
W_zeropadded = fft(window, 2048) / len(window)&lt;br /&gt;
widmo_zeropadded = abs(fftshift(W_zeropadded))&lt;br /&gt;
f = np.linspace(-0.5,0.5,len(W_zeropadded))&lt;br /&gt;
widmo_dB_zeropadded = 20*np.log10(widmo_zeropadded)&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(f ,widmo_dB_zeropadded)&lt;br /&gt;
py.title(&amp;quot;widmo okna Bartletta&amp;quot;)&lt;br /&gt;
py.ylabel(u&amp;quot;Wartość [dB]&amp;quot;)&lt;br /&gt;
py.xlabel(u&amp;quot;znormalizowana częstość&amp;quot;)&lt;br /&gt;
py.axis('tight')&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* A jakie własności ma okno prostokątne? Najprościej można je zrobić tak: &amp;lt;tt&amp;gt;window = np.ones(N)&amp;lt;/tt&amp;gt;. Proszę wykonać analogiczne rysunki jak dla okna Bartletta.&lt;br /&gt;
&lt;br /&gt;
* Proszę porównać przebiegi czasowe i własności widmowe pozostałych okien dostępnych w scipy.signal, m.in.: &lt;br /&gt;
**blackman(M) 	&lt;br /&gt;
**hamming(M) 	&lt;br /&gt;
**hanning(M) 	&lt;br /&gt;
**kaiser(M, beta)&lt;br /&gt;
&lt;br /&gt;
===Własności okien w działaniu===&lt;br /&gt;
==== Okienko i szerokość prążka w widmie ====&lt;br /&gt;
* Wygeneruj sinusoidę o częstości &amp;lt;math&amp;gt;f=10.2&amp;lt;/math&amp;gt; Hz fazie 0, czasie trwania &amp;lt;math&amp;gt;T=1&amp;lt;/math&amp;gt; s, i częstości próbkowania &amp;lt;math&amp;gt;Fs=100&amp;lt;/math&amp;gt; Hz&lt;br /&gt;
* Wygeneruj okno prostokątne o długości równej długości sinusoidy.&lt;br /&gt;
* Zokienkuj sygnał mnożąc sinusoidę przez okienko&lt;br /&gt;
* Wykreśl zokienkowany sygnał, widmo zokienkowanego sygnału, widmo okienka&lt;br /&gt;
* Powtórz powyższe kroki dla okienek Bartletta, Hanna, Hamminga i Blackmana. Przy wykreślaniu widma zokienkowanego sygnału ustal zakres osi pionowej na [-50 10] (zastosuj &amp;lt;tt&amp;gt;py.ylim((-50,10)&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
* Proszę porównać widma otrzymane dla poszczególnych typów okienek.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 10.2, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,1)&lt;br /&gt;
okno = np.ones(len(x))/np.sqrt(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany prostokątem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,2)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego prostokątem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,3)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo prostokąta')&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,4)&lt;br /&gt;
okno = np.blackman(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Blackmanem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,5)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Blackmanem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,6)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Blackmana')&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,7)&lt;br /&gt;
okno = np.hamming(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Hamming')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,8)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Hamming')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,9)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Hamming')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
====Wpływ okienkowania na wykrywalność składowych o różnej amplitudzie ====&lt;br /&gt;
* Wygeneruj sygnał będący sumą dwóch sinusoid o fazie 0, czasie trwania &amp;lt;math&amp;gt;T=1&amp;lt;/math&amp;gt; s, i częstości próbkowania &amp;lt;math&amp;gt;Fs=100&amp;lt;/math&amp;gt; Hz. Jedna niech ma częstość &amp;lt;math&amp;gt;f=10.2&amp;lt;/math&amp;gt; Hz. Częstość drugiej, w kolejnych zapuszczeniach skryptu proszę zmieniać od 11,4 do 16,4 Hz z krokiem co 0,5 Hz.&lt;br /&gt;
* Jaki jest wpływ okienek na możliwości rozróżnienia dwóch częstości?&lt;br /&gt;
* Proszę powtórzyć iteracje dla przypadku gdy druga z sinusoid ma 10-krotnie niższą amplitudę.&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source  lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x1,t) = sin(f = 10.2, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
&lt;br /&gt;
(x2,t) = sin(f = 11.4+0.5*1, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
x = x1 + 1*x2 #0.1*&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,1)&lt;br /&gt;
okno = np.ones(len(x))/np.sqrt(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany prostokątem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,2)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego prostokątem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,3)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo prostokąta')&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,4)&lt;br /&gt;
okno = np.blackman(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Blackmanem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,5)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Blackmanem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,6)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Blackmana')&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,7)&lt;br /&gt;
okno = np.hamming(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Hamming')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,8)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Hamming')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,9)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Hamming')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Okienkować możemy też w częstości===&lt;br /&gt;
&lt;br /&gt;
* Proszę wykreślić widmo, a następie obliczyć i wykreślić [[%C4%86wiczenia_2#Transformaty_rzeczywiste_i_Hermitowskie|odwrotną transformatę Fouriera dla sygnału rzeczywistego]] zadanego w dziedzinie częstości przez (poniższy kod definiuje sygnał w dodatniej części widma):&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
S = np.zeros(128)&lt;br /&gt;
S[21] = 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Proszę wykreślić okienko prostokątne w częstości, pozycja 1 w binach częstości od 21 do 30, a następnie wykreślić odpowiadający mu sygnał w dziedzinie czasu.&lt;br /&gt;
&lt;br /&gt;
* Koncepcyjnie najprostszym filtrem jest operacja przemnożenia widma sygnału przez okienko w dziedzinie częstości a następnie zastosowanie odwrotnej transformaty Fouriera. Co stanie się z sygnałem w dziedzinie czasu, a co w dziedzinie częstości, jeśli chcielibyśmy przefiltrować go pasmowo przy użyciu filtra pasmowo przepustowego z poprzedniego punktu?&lt;br /&gt;
 * &amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  irfft,fftshift&lt;br /&gt;
 &lt;br /&gt;
S= np.zeros(128)&lt;br /&gt;
S[21:28] = 1&lt;br /&gt;
&lt;br /&gt;
s = fftshift(irfft(S))&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
F = range(len(S))&lt;br /&gt;
py.stem(F,S)&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
t = range(len(s))&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Porównajmy działanie najprostszych filtrów fft na biały szum.&lt;br /&gt;
** Proszę wytworzyć sygnał będący białym szumem o długości 256 próbek.&lt;br /&gt;
** Policz transformatę rzeczywistą tego sygnału.&lt;br /&gt;
** Przygotuj dwa okna w dziedzinie częstości (w części dodatniej)  o długości 129: &lt;br /&gt;
*** okno prostokątne  z jedynkami w punktach 20:30&lt;br /&gt;
*** okno Gaussowskie &amp;lt;tt&amp;gt;np.exp(-((F-25.0)/5)**2)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Przemnóż widmo sygnału przez każde z okien i oblicz odwrotną transformatę Fouriera. &lt;br /&gt;
** Zilustruj wyniki rysunkiem opisanym przez poniższą tabelkę:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|border = 1&lt;br /&gt;
|okno prostokątne w częstości &lt;br /&gt;
| okno Gaussowskie w częstości&lt;br /&gt;
|-&lt;br /&gt;
|przebieg czasowy odwrotnej tr. Fouriera okna Prostokątnego &lt;br /&gt;
|przebieg czasowy odwrotnej tr. Fouriera okna Gaussowskiego&lt;br /&gt;
|-&lt;br /&gt;
|przebieg czasowy szumu&lt;br /&gt;
|przebieg czasowy szumu&lt;br /&gt;
|-&lt;br /&gt;
|Przebieg czasowy odwrotnej tr. Fouriera iloczynu widma szumu i okna prostokątnego&lt;br /&gt;
|Przebieg czasowy odwrotnej tr. Fouriera iloczynu widma szumu i okna Gaussowskiego&lt;br /&gt;
|}&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  irfft,rfft,fftshift&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
szum = np.random.randn(128*2-2)&lt;br /&gt;
SZum = rfft(szum)&lt;br /&gt;
&lt;br /&gt;
S_prost= np.zeros(128)&lt;br /&gt;
S_prost[20:30]=1&lt;br /&gt;
s_prost = fftshift(irfft(S_prost))&lt;br /&gt;
&lt;br /&gt;
t = np.arange(len(s_prost))&lt;br /&gt;
F = np.arange(len(S_prost))&lt;br /&gt;
S_gauss = np.exp(-((F-25.0)/5)**2)&lt;br /&gt;
s_gauss = fftshift(irfft(S_gauss))&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,1)&lt;br /&gt;
py.stem(F,S_prost)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,3)&lt;br /&gt;
py.plot(t,s_prost)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,5)&lt;br /&gt;
py.plot(t,szum)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,7)&lt;br /&gt;
filtrowanySygnal = fftshift(irfft(SZum*S_prost))&lt;br /&gt;
py.plot(filtrowanySygnal)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,2)&lt;br /&gt;
py.stem(F,S_gauss)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,4)&lt;br /&gt;
py.plot(t,s_gauss)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,6)&lt;br /&gt;
py.plot(t,szum)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,8)&lt;br /&gt;
filtrowanySignal = fftshift(irfft(SZum*S_gauss))&lt;br /&gt;
py.plot(filtrowanySignal)&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_3&amp;diff=4244</id>
		<title>Ćwiczenia 3</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_3&amp;diff=4244"/>
		<updated>2015-10-05T09:22:04Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Badanie własności okien */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Twierdzenie o splocie ==&lt;br /&gt;
Na pierwszych ćwiczeniach poznaliśmy poznaliśmy operację [[Systemy_liniowe_niezmiennicze_w_czasie#Splot|splotu]] jako efekt działania systemu liniowego niezmienniczego w czasie. Poznaliśmy wówczas jego [[Systemy_liniowe_niezmiennicze_w_czasie#W.C5.82asno.C5.9Bci_splotu|własności]].&lt;br /&gt;
Okazuje się, że gdy rozważamy sprzężone ze sobą za pomocą transformaty Fouriera dziedziny czasu i częstości splot ma wiele wspólnego z mnożeniem. Związek ten można zapisać jako &lt;br /&gt;
[[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|Twierdzenie o splocie:]] &lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid2&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
g(t)=\left(s * h\right)(t)\quad \Rightarrow \quad G(f)=S(f)\cdot H(f)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
To twierdzenie działa też w drugą stronę:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
G(f)=\left(S * H\right)(f)\quad \Rightarrow \quad g(t)=s(t)\cdot h(t)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W praktyce oznacza to tyle, że jeśli w jednej dziedzinie jakieś dwa sygnały przez siebie przemnożymy, to w drugiej dziedzinie transformaty tych sygnałów splatają się. Własność ta ma bardzo ważne konsekwencje, np. przy estymacji widma skończonego fragmentu sygnału. Dlaczego?&lt;br /&gt;
&lt;br /&gt;
Wyobraźmy sobie, że mamy nieskończenie długi sygnał. Oprócz niego mamy też funkcję, która jest niezerowa tylko na skończonym odcinku. Funkcję taką będziemy nazywać oknem. Pobranie fragmentu sygnału można wyobrazić sobie jako efekt pomnożenia badanego sygnału przez okno. Ta operacja mnożenia w dziedzinie czasu, w dziedzinie częstości odpowiada splotowi widma sygnału z widmem okna. Aby uzyskać sygnał o skończonej długości odrzucamy wyzerowane odcinki. FFT widzi taki skończony odcinek jako  [[%C4%86wiczenia_2#Przed.C5.82u.C5.BCenie_przez_periodyczn.C4.85_replikacj.C4.99|periodyczne przedłużenie]].  Widać, że w praktyce estymowania widma zawsze mamy  do czynienia z widmami będącymi splotem widma sygnału i widma okna, ponieważ zawsze pracujemy z sygnałami o skończonej długości.&lt;br /&gt;
&lt;br /&gt;
===Zastosowania===&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	zamiana splotu na mnożenie&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	daje wgląd w okienkowanie&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	łatwo zrozumieć działanie filtrów&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Okienka==&lt;br /&gt;
===Wstęp===&lt;br /&gt;
* Jakie są dostępne okna w scipy.signal? Proszę odwiedzić stronę z [http://docs.scipy.org/doc/scipy-0.14.0/reference/signal.html dokumentacją].&lt;br /&gt;
* Jak wyglądają te okienka?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
from scipy import signal&lt;br /&gt;
w = signal.bartlett(10)&lt;br /&gt;
print(w)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Badanie własności okien===&lt;br /&gt;
&lt;br /&gt;
* Wykreśl okienko Bartletta o długości 100 i 101 próbek.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as py&lt;br /&gt;
&lt;br /&gt;
window = np.bartlett(101)&lt;br /&gt;
py.plot(window)&lt;br /&gt;
py.title(&amp;quot;okno Bartletta&amp;quot;)&lt;br /&gt;
py.ylabel(&amp;quot;Amplituda&amp;quot;)&lt;br /&gt;
py.xlabel(u&amp;quot;próbki&amp;quot;)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Proszę wykreślić widmo amplitudowe okna Bartletta o długości 101 próbek w skali [[wikipl:Decybel|dB]] (&amp;lt;tt&amp;gt;20*np.log10(.)&amp;lt;/tt&amp;gt;), raz korzystając z fft o naturalnej długości okna &amp;lt;tt&amp;gt;W = fft(okno)&amp;lt;/tt&amp;gt;, a drugi raz korzystając z przedłużenia zerami (w tym przypadku dostaniemy interpolowaną wersję widma) &amp;lt;tt&amp;gt;W = fft(okno, 2048)&amp;lt;/tt&amp;gt;. Proszę zwrócić uwagę na charakterystyczne elementy: szerokość piku głównego, szybkość zanikania listków bocznych, zera. &lt;br /&gt;
&lt;br /&gt;
Przydatna może być tu funkcja do obliczania widma (proszę przeanalizować kod i w razie wątpliwości poprosić o objaśnienie):&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
&lt;br /&gt;
def widmo_dB(s, N_fft, F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1.0/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 *&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import fft, fftshift&lt;br /&gt;
import matplotlib.pyplot as py&lt;br /&gt;
&lt;br /&gt;
window = np.bartlett(51)&lt;br /&gt;
&lt;br /&gt;
W = fft(window)/len(window)&lt;br /&gt;
# rysować będziemy w skali logarytmicznej&lt;br /&gt;
widmo = abs(fftshift(W))&lt;br /&gt;
widmo_dB = 20*np.log10(widmo)&lt;br /&gt;
f = np.linspace(-0.5,0.5,len(W))&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(f,widmo_dB)&lt;br /&gt;
py.axis('tight')&lt;br /&gt;
&lt;br /&gt;
W_zeropadded = fft(window, 2048) / len(window)&lt;br /&gt;
widmo_zeropadded = abs(fftshift(W_zeropadded))&lt;br /&gt;
f = np.linspace(-0.5,0.5,len(W_zeropadded))&lt;br /&gt;
widmo_dB_zeropadded = 20*np.log10(widmo_zeropadded)&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(f ,widmo_dB_zeropadded)&lt;br /&gt;
py.title(&amp;quot;widmo okna Bartletta&amp;quot;)&lt;br /&gt;
py.ylabel(u&amp;quot;Wartość [dB]&amp;quot;)&lt;br /&gt;
py.xlabel(u&amp;quot;znormalizowana częstość&amp;quot;)&lt;br /&gt;
py.axis('tight')&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* A jakie własności ma okno prostokątne? Najprościej można je zrobić tak: &amp;lt;tt&amp;gt;window = np.ones(N)&amp;lt;/tt&amp;gt;. Proszę wykonać analogiczne rysunki jak dla okna Bartletta.&lt;br /&gt;
&lt;br /&gt;
* Proszę porównać przebiegi czasowe i własności widmowe pozostałych okien dostępnych w scipy.signal, m.in.: &lt;br /&gt;
**blackman(M) 	&lt;br /&gt;
**hamming(M) 	&lt;br /&gt;
**hanning(M) 	&lt;br /&gt;
**kaiser(M, beta)&lt;br /&gt;
&lt;br /&gt;
===Własności okien w działaniu===&lt;br /&gt;
==== Okienko i szerokość prążka w widmie ====&lt;br /&gt;
* Wygeneruj sinusoidę o częstości &amp;lt;math&amp;gt;f=10.2&amp;lt;/math&amp;gt; Hz fazie 0, czasie trwania &amp;lt;math&amp;gt;T=1&amp;lt;/math&amp;gt; s, i częstości próbkowania &amp;lt;math&amp;gt;Fs=100&amp;lt;/math&amp;gt; Hz&lt;br /&gt;
* Wygeneruj okno prostokątne o długości równej długości sinusoidy.&lt;br /&gt;
* Zokienkuj sygnał mnożąc sinusoidę przez okienko&lt;br /&gt;
* Wykreśl zokienkowany sygnał, widmo zokienkowanego sygnału, widmo okienka&lt;br /&gt;
* Powtórz powyższe kroki dla okienek Bartletta, Hanna, Hamminga i Blackmana. Przy wykreślaniu widma zokienkowanego sygnału ustal zakres osi pionowej na [-50 10] (zastosuj &amp;lt;tt&amp;gt;py.ylim((-50,10)&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
* Proszę porównać widma otrzymane dla poszczególnych typów okienek.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 10.2, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,1)&lt;br /&gt;
okno = np.ones(len(x))/np.sqrt(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany prostokątem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,2)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego prostokątem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,3)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo prostokąta')&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,4)&lt;br /&gt;
okno = np.blackman(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Blackmanem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,5)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Blackmanem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,6)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Blackmana')&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,7)&lt;br /&gt;
okno = np.hamming(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Hamming')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,8)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Hamming')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,9)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Hamming')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
====Wpływ okienkowania na wykrywalność składowych o różnej amplitudzie ====&lt;br /&gt;
* Wygeneruj sygnał będący sumą dwóch sinusoid o fazie 0, czasie trwania &amp;lt;math&amp;gt;T=1&amp;lt;/math&amp;gt; s, i częstości próbkowania &amp;lt;math&amp;gt;Fs=100&amp;lt;/math&amp;gt; Hz. Jedna niech ma częstość &amp;lt;math&amp;gt;f=10.2&amp;lt;/math&amp;gt; Hz. Częstość drugiej, w kolejnych zapuszczeniach skryptu proszę zmieniać od 11,4 do 16,4 Hz z krokiem co 0,5 Hz.&lt;br /&gt;
* Jaki jest wpływ okienek na możliwości rozróżnienia dwóch częstości?&lt;br /&gt;
* Proszę powtórzyć iteracje dla przypadku gdy druga z sinusoid ma 10-krotnie niższą amplitudę.&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source  lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x1,t) = sin(f = 10.2, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
&lt;br /&gt;
(x2,t) = sin(f = 11.4+0.5*1, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
x = x1 + 1*x2 #0.1*&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,1)&lt;br /&gt;
okno = np.ones(len(x))/np.sqrt(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany prostokątem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,2)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego prostokątem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,3)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo prostokąta')&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,4)&lt;br /&gt;
okno = np.blackman(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Blackmanem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,5)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Blackmanem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,6)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Blackmana')&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,7)&lt;br /&gt;
okno = np.hamming(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Hamming')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,8)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Hamming')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,9)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Hamming')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Okienkować możemy też w częstości===&lt;br /&gt;
&lt;br /&gt;
* Proszę wykreślić widmo, a następie obliczyć i wykreślić [[%C4%86wiczenia_2#Transformaty_rzeczywiste_i_Hermitowskie|odwrotną transformatę Fouriera dla sygnału rzeczywistego]] zadanego w dziedzinie częstości przez (poniższy kod definiuje sygnał w dodatniej części widma):&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
S = np.zeros(128)&lt;br /&gt;
S[21] = 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Proszę wykreślić okienko prostokątne w częstości, pozycja 1 w binach częstości od 21 do 30, a następnie wykreślić odpowiadający mu sygnał w dziedzinie czasu.&lt;br /&gt;
&lt;br /&gt;
* Koncepcyjnie najprostszym filtrem jest operacja przemnożenia widma sygnału przez okienko w dziedzinie częstości a następnie zastosowanie odwrotnej transformaty Fouriera. Co stanie się z sygnałem w dziedzinie czasu, a co w dziedzinie częstości, jeśli chcielibyśmy przefiltrować go pasmowo przy użyciu filtra pasmowo przepustowego z poprzedniego punktu?&lt;br /&gt;
 * &amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  irfft,fftshift&lt;br /&gt;
 &lt;br /&gt;
S= np.zeros(128)&lt;br /&gt;
S[21:28] = 1&lt;br /&gt;
&lt;br /&gt;
s = fftshift(irfft(S))&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
F = range(len(S))&lt;br /&gt;
py.stem(F,S)&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
t = range(len(s))&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Porównajmy działanie najprostszych filtrów fft na biały szum.&lt;br /&gt;
** Proszę wytworzyć sygnał będący białym szumem o długości 256 próbek.&lt;br /&gt;
** Policz transformatę rzeczywistą tego sygnału.&lt;br /&gt;
** Przygotuj dwa okna w dziedzinie częstości (w części dodatniej)  o długości 129: &lt;br /&gt;
*** okno prostokątne  z jedynkami w punktach 20:30&lt;br /&gt;
*** okno Gaussowskie &amp;lt;tt&amp;gt;np.exp(-((F-25.0)/5)**2)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Przemnóż widmo sygnału przez każde z okien i oblicz odwrotną transformatę Fouriera. &lt;br /&gt;
** Zilustruj wyniki rysunkiem opisanym przez poniższą tabelkę:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|border = 1&lt;br /&gt;
|okno prostokątne w częstości &lt;br /&gt;
| okno Gaussowskie w częstości&lt;br /&gt;
|-&lt;br /&gt;
|przebieg czasowy odwrotnej tr. Fouriera okna Prostokątnego &lt;br /&gt;
|przebieg czasowy odwrotnej tr. Fouriera okna Gaussowskiego&lt;br /&gt;
|-&lt;br /&gt;
|przebieg czasowy szumu&lt;br /&gt;
|przebieg czasowy szumu&lt;br /&gt;
|-&lt;br /&gt;
|Przebieg czasowy odwrotnej tr. Fouriera iloczynu widma szumu i okna prostokątnego&lt;br /&gt;
|Przebieg czasowy odwrotnej tr. Fouriera iloczynu widma szumu i okna Gaussowskiego&lt;br /&gt;
|}&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  irfft,rfft,fftshift&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
szum = np.random.randn(128*2-2)&lt;br /&gt;
SZum = rfft(szum)&lt;br /&gt;
&lt;br /&gt;
S_prost= np.zeros(128)&lt;br /&gt;
S_prost[20:30]=1&lt;br /&gt;
s_prost = fftshift(irfft(S_prost))&lt;br /&gt;
&lt;br /&gt;
t = np.arange(len(s_prost))&lt;br /&gt;
F = np.arange(len(S_prost))&lt;br /&gt;
S_gauss = np.exp(-((F-25.0)/5)**2)&lt;br /&gt;
s_gauss = fftshift(irfft(S_gauss))&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,1)&lt;br /&gt;
py.stem(F,S_prost)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,3)&lt;br /&gt;
py.plot(t,s_prost)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,5)&lt;br /&gt;
py.plot(t,szum)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,7)&lt;br /&gt;
filtrowanySygnal = fftshift(irfft(SZum*S_prost))&lt;br /&gt;
py.plot(filtrowanySygnal)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,2)&lt;br /&gt;
py.stem(F,S_gauss)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,4)&lt;br /&gt;
py.plot(t,s_gauss)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,6)&lt;br /&gt;
py.plot(t,szum)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,8)&lt;br /&gt;
filtrowanySignal = fftshift(irfft(SZum*S_gauss))&lt;br /&gt;
py.plot(filtrowanySignal)&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_3&amp;diff=4243</id>
		<title>Ćwiczenia 3</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_3&amp;diff=4243"/>
		<updated>2015-10-05T09:20:11Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Badanie własności okien */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Twierdzenie o splocie ==&lt;br /&gt;
Na pierwszych ćwiczeniach poznaliśmy poznaliśmy operację [[Systemy_liniowe_niezmiennicze_w_czasie#Splot|splotu]] jako efekt działania systemu liniowego niezmienniczego w czasie. Poznaliśmy wówczas jego [[Systemy_liniowe_niezmiennicze_w_czasie#W.C5.82asno.C5.9Bci_splotu|własności]].&lt;br /&gt;
Okazuje się, że gdy rozważamy sprzężone ze sobą za pomocą transformaty Fouriera dziedziny czasu i częstości splot ma wiele wspólnego z mnożeniem. Związek ten można zapisać jako &lt;br /&gt;
[[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|Twierdzenie o splocie:]] &lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid2&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
g(t)=\left(s * h\right)(t)\quad \Rightarrow \quad G(f)=S(f)\cdot H(f)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
To twierdzenie działa też w drugą stronę:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
G(f)=\left(S * H\right)(f)\quad \Rightarrow \quad g(t)=s(t)\cdot h(t)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W praktyce oznacza to tyle, że jeśli w jednej dziedzinie jakieś dwa sygnały przez siebie przemnożymy, to w drugiej dziedzinie transformaty tych sygnałów splatają się. Własność ta ma bardzo ważne konsekwencje, np. przy estymacji widma skończonego fragmentu sygnału. Dlaczego?&lt;br /&gt;
&lt;br /&gt;
Wyobraźmy sobie, że mamy nieskończenie długi sygnał. Oprócz niego mamy też funkcję, która jest niezerowa tylko na skończonym odcinku. Funkcję taką będziemy nazywać oknem. Pobranie fragmentu sygnału można wyobrazić sobie jako efekt pomnożenia badanego sygnału przez okno. Ta operacja mnożenia w dziedzinie czasu, w dziedzinie częstości odpowiada splotowi widma sygnału z widmem okna. Aby uzyskać sygnał o skończonej długości odrzucamy wyzerowane odcinki. FFT widzi taki skończony odcinek jako  [[%C4%86wiczenia_2#Przed.C5.82u.C5.BCenie_przez_periodyczn.C4.85_replikacj.C4.99|periodyczne przedłużenie]].  Widać, że w praktyce estymowania widma zawsze mamy  do czynienia z widmami będącymi splotem widma sygnału i widma okna, ponieważ zawsze pracujemy z sygnałami o skończonej długości.&lt;br /&gt;
&lt;br /&gt;
===Zastosowania===&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	zamiana splotu na mnożenie&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	daje wgląd w okienkowanie&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	łatwo zrozumieć działanie filtrów&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Okienka==&lt;br /&gt;
===Wstęp===&lt;br /&gt;
* Jakie są dostępne okna w scipy.signal? Proszę odwiedzić stronę z [http://docs.scipy.org/doc/scipy-0.14.0/reference/signal.html dokumentacją].&lt;br /&gt;
* Jak wyglądają te okienka?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
from scipy import signal&lt;br /&gt;
w = signal.bartlett(10)&lt;br /&gt;
print(w)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Badanie własności okien===&lt;br /&gt;
&lt;br /&gt;
* Wykreśl okienko Bartletta o długości 100 i 101 próbek.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as py&lt;br /&gt;
&lt;br /&gt;
window = np.bartlett(101)&lt;br /&gt;
py.plot(window)&lt;br /&gt;
py.title(&amp;quot;okno Bartletta&amp;quot;)&lt;br /&gt;
py.ylabel(&amp;quot;Amplituda&amp;quot;)&lt;br /&gt;
py.xlabel(u&amp;quot;próbki&amp;quot;)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Proszę wykreślić widmo amplitudowe okna Bartletta o długości 101 próbek w skali [[wikipl:Decybel|dB]] (&amp;lt;tt&amp;gt;20*np.log10(.)&amp;lt;/tt&amp;gt;), raz korzystając z fft o naturalnej długości okna &amp;lt;tt&amp;gt;W = fft(okno)&amp;lt;/tt&amp;gt;, a drugi raz korzystając z przedłużenia zerami (w tym przypadku dostaniemy interpolowaną wersję widma) &amp;lt;tt&amp;gt;W = fft(okno, 2048)&amp;lt;/tt&amp;gt;. Proszę zwrócić uwagę na charakterystyczne elementy: szerokość piku głównego, szybkość zanikania listków bocznych, zera. &lt;br /&gt;
&lt;br /&gt;
Przydatna może być tu funkcja do obliczania widma (proszę przeanalizować kod i w razie wątpliwości poprosić o objaśnienie):&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
&lt;br /&gt;
def widmo_dB(s, N_fft, F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1.0/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 *&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import fft, fftshift&lt;br /&gt;
import matplotlib.pyplot as py&lt;br /&gt;
&lt;br /&gt;
window = np.bartlett(51)&lt;br /&gt;
&lt;br /&gt;
W = fft(window)/len(window)&lt;br /&gt;
# rysować będziemy w skali logarytmicznej&lt;br /&gt;
widmo = abs(fftshift(W))&lt;br /&gt;
widmo_dB = 20*np.log10(widmo)&lt;br /&gt;
f = np.linspace(-0.5,0.5,len(W))&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(f,widmo_dB)&lt;br /&gt;
py.axis('tight')&lt;br /&gt;
&lt;br /&gt;
W_zeropadded = fft(window, 2048) / len(window)&lt;br /&gt;
widmo_zeropadded = abs(fftshift(W_zeropadded))&lt;br /&gt;
f = np.linspace(-0.5,0.5,len(W_zeropadded))&lt;br /&gt;
widmo_dB_zeropadded = 20*np.log10(widmo_zeropadded)&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(f ,widmo_dB_zeropadded)&lt;br /&gt;
py.title(&amp;quot;widmo okna Bartletta&amp;quot;)&lt;br /&gt;
py.ylabel(u&amp;quot;Wartość [dB]&amp;quot;)&lt;br /&gt;
py.xlabel(u&amp;quot;znormalizowana częstość&amp;quot;)&lt;br /&gt;
py.axis('tight')&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* A jakie własności ma okno prostokątne? Najprościej można je zrobić tak: &amp;lt;tt&amp;gt;window = np.ones(N)&amp;lt;/tt&amp;gt;. Proszę wykonać analogiczne rysunki jak dla okna Bartletta.&lt;br /&gt;
&lt;br /&gt;
* Proszę porównać przebiegi czasowe i własności widmowe pozostałych okien dostępnych w numpy, tzn.: &lt;br /&gt;
**blackman(M) 	&lt;br /&gt;
**hamming(M) 	&lt;br /&gt;
**hanning(M) 	&lt;br /&gt;
**kaiser(M, beta)&lt;br /&gt;
&lt;br /&gt;
===Własności okien w działaniu===&lt;br /&gt;
==== Okienko i szerokość prążka w widmie ====&lt;br /&gt;
* Wygeneruj sinusoidę o częstości &amp;lt;math&amp;gt;f=10.2&amp;lt;/math&amp;gt; Hz fazie 0, czasie trwania &amp;lt;math&amp;gt;T=1&amp;lt;/math&amp;gt; s, i częstości próbkowania &amp;lt;math&amp;gt;Fs=100&amp;lt;/math&amp;gt; Hz&lt;br /&gt;
* Wygeneruj okno prostokątne o długości równej długości sinusoidy.&lt;br /&gt;
* Zokienkuj sygnał mnożąc sinusoidę przez okienko&lt;br /&gt;
* Wykreśl zokienkowany sygnał, widmo zokienkowanego sygnału, widmo okienka&lt;br /&gt;
* Powtórz powyższe kroki dla okienek Bartletta, Hanna, Hamminga i Blackmana. Przy wykreślaniu widma zokienkowanego sygnału ustal zakres osi pionowej na [-50 10] (zastosuj &amp;lt;tt&amp;gt;py.ylim((-50,10)&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
* Proszę porównać widma otrzymane dla poszczególnych typów okienek.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 10.2, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,1)&lt;br /&gt;
okno = np.ones(len(x))/np.sqrt(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany prostokątem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,2)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego prostokątem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,3)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo prostokąta')&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,4)&lt;br /&gt;
okno = np.blackman(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Blackmanem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,5)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Blackmanem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,6)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Blackmana')&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,7)&lt;br /&gt;
okno = np.hamming(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Hamming')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,8)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Hamming')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,9)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Hamming')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
====Wpływ okienkowania na wykrywalność składowych o różnej amplitudzie ====&lt;br /&gt;
* Wygeneruj sygnał będący sumą dwóch sinusoid o fazie 0, czasie trwania &amp;lt;math&amp;gt;T=1&amp;lt;/math&amp;gt; s, i częstości próbkowania &amp;lt;math&amp;gt;Fs=100&amp;lt;/math&amp;gt; Hz. Jedna niech ma częstość &amp;lt;math&amp;gt;f=10.2&amp;lt;/math&amp;gt; Hz. Częstość drugiej, w kolejnych zapuszczeniach skryptu proszę zmieniać od 11,4 do 16,4 Hz z krokiem co 0,5 Hz.&lt;br /&gt;
* Jaki jest wpływ okienek na możliwości rozróżnienia dwóch częstości?&lt;br /&gt;
* Proszę powtórzyć iteracje dla przypadku gdy druga z sinusoid ma 10-krotnie niższą amplitudę.&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source  lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x1,t) = sin(f = 10.2, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
&lt;br /&gt;
(x2,t) = sin(f = 11.4+0.5*1, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
x = x1 + 1*x2 #0.1*&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,1)&lt;br /&gt;
okno = np.ones(len(x))/np.sqrt(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany prostokątem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,2)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego prostokątem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,3)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo prostokąta')&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,4)&lt;br /&gt;
okno = np.blackman(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Blackmanem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,5)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Blackmanem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,6)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Blackmana')&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,7)&lt;br /&gt;
okno = np.hamming(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Hamming')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,8)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Hamming')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,9)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Hamming')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Okienkować możemy też w częstości===&lt;br /&gt;
&lt;br /&gt;
* Proszę wykreślić widmo, a następie obliczyć i wykreślić [[%C4%86wiczenia_2#Transformaty_rzeczywiste_i_Hermitowskie|odwrotną transformatę Fouriera dla sygnału rzeczywistego]] zadanego w dziedzinie częstości przez (poniższy kod definiuje sygnał w dodatniej części widma):&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
S = np.zeros(128)&lt;br /&gt;
S[21] = 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Proszę wykreślić okienko prostokątne w częstości, pozycja 1 w binach częstości od 21 do 30, a następnie wykreślić odpowiadający mu sygnał w dziedzinie czasu.&lt;br /&gt;
&lt;br /&gt;
* Koncepcyjnie najprostszym filtrem jest operacja przemnożenia widma sygnału przez okienko w dziedzinie częstości a następnie zastosowanie odwrotnej transformaty Fouriera. Co stanie się z sygnałem w dziedzinie czasu, a co w dziedzinie częstości, jeśli chcielibyśmy przefiltrować go pasmowo przy użyciu filtra pasmowo przepustowego z poprzedniego punktu?&lt;br /&gt;
 * &amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  irfft,fftshift&lt;br /&gt;
 &lt;br /&gt;
S= np.zeros(128)&lt;br /&gt;
S[21:28] = 1&lt;br /&gt;
&lt;br /&gt;
s = fftshift(irfft(S))&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
F = range(len(S))&lt;br /&gt;
py.stem(F,S)&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
t = range(len(s))&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Porównajmy działanie najprostszych filtrów fft na biały szum.&lt;br /&gt;
** Proszę wytworzyć sygnał będący białym szumem o długości 256 próbek.&lt;br /&gt;
** Policz transformatę rzeczywistą tego sygnału.&lt;br /&gt;
** Przygotuj dwa okna w dziedzinie częstości (w części dodatniej)  o długości 129: &lt;br /&gt;
*** okno prostokątne  z jedynkami w punktach 20:30&lt;br /&gt;
*** okno Gaussowskie &amp;lt;tt&amp;gt;np.exp(-((F-25.0)/5)**2)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Przemnóż widmo sygnału przez każde z okien i oblicz odwrotną transformatę Fouriera. &lt;br /&gt;
** Zilustruj wyniki rysunkiem opisanym przez poniższą tabelkę:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|border = 1&lt;br /&gt;
|okno prostokątne w częstości &lt;br /&gt;
| okno Gaussowskie w częstości&lt;br /&gt;
|-&lt;br /&gt;
|przebieg czasowy odwrotnej tr. Fouriera okna Prostokątnego &lt;br /&gt;
|przebieg czasowy odwrotnej tr. Fouriera okna Gaussowskiego&lt;br /&gt;
|-&lt;br /&gt;
|przebieg czasowy szumu&lt;br /&gt;
|przebieg czasowy szumu&lt;br /&gt;
|-&lt;br /&gt;
|Przebieg czasowy odwrotnej tr. Fouriera iloczynu widma szumu i okna prostokątnego&lt;br /&gt;
|Przebieg czasowy odwrotnej tr. Fouriera iloczynu widma szumu i okna Gaussowskiego&lt;br /&gt;
|}&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  irfft,rfft,fftshift&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
szum = np.random.randn(128*2-2)&lt;br /&gt;
SZum = rfft(szum)&lt;br /&gt;
&lt;br /&gt;
S_prost= np.zeros(128)&lt;br /&gt;
S_prost[20:30]=1&lt;br /&gt;
s_prost = fftshift(irfft(S_prost))&lt;br /&gt;
&lt;br /&gt;
t = np.arange(len(s_prost))&lt;br /&gt;
F = np.arange(len(S_prost))&lt;br /&gt;
S_gauss = np.exp(-((F-25.0)/5)**2)&lt;br /&gt;
s_gauss = fftshift(irfft(S_gauss))&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,1)&lt;br /&gt;
py.stem(F,S_prost)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,3)&lt;br /&gt;
py.plot(t,s_prost)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,5)&lt;br /&gt;
py.plot(t,szum)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,7)&lt;br /&gt;
filtrowanySygnal = fftshift(irfft(SZum*S_prost))&lt;br /&gt;
py.plot(filtrowanySygnal)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,2)&lt;br /&gt;
py.stem(F,S_gauss)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,4)&lt;br /&gt;
py.plot(t,s_gauss)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,6)&lt;br /&gt;
py.plot(t,szum)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,8)&lt;br /&gt;
filtrowanySignal = fftshift(irfft(SZum*S_gauss))&lt;br /&gt;
py.plot(filtrowanySignal)&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_3&amp;diff=4242</id>
		<title>Ćwiczenia 3</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_3&amp;diff=4242"/>
		<updated>2015-10-05T09:19:35Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Wstęp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Twierdzenie o splocie ==&lt;br /&gt;
Na pierwszych ćwiczeniach poznaliśmy poznaliśmy operację [[Systemy_liniowe_niezmiennicze_w_czasie#Splot|splotu]] jako efekt działania systemu liniowego niezmienniczego w czasie. Poznaliśmy wówczas jego [[Systemy_liniowe_niezmiennicze_w_czasie#W.C5.82asno.C5.9Bci_splotu|własności]].&lt;br /&gt;
Okazuje się, że gdy rozważamy sprzężone ze sobą za pomocą transformaty Fouriera dziedziny czasu i częstości splot ma wiele wspólnego z mnożeniem. Związek ten można zapisać jako &lt;br /&gt;
[[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|Twierdzenie o splocie:]] &lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid2&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
g(t)=\left(s * h\right)(t)\quad \Rightarrow \quad G(f)=S(f)\cdot H(f)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
To twierdzenie działa też w drugą stronę:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
G(f)=\left(S * H\right)(f)\quad \Rightarrow \quad g(t)=s(t)\cdot h(t)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W praktyce oznacza to tyle, że jeśli w jednej dziedzinie jakieś dwa sygnały przez siebie przemnożymy, to w drugiej dziedzinie transformaty tych sygnałów splatają się. Własność ta ma bardzo ważne konsekwencje, np. przy estymacji widma skończonego fragmentu sygnału. Dlaczego?&lt;br /&gt;
&lt;br /&gt;
Wyobraźmy sobie, że mamy nieskończenie długi sygnał. Oprócz niego mamy też funkcję, która jest niezerowa tylko na skończonym odcinku. Funkcję taką będziemy nazywać oknem. Pobranie fragmentu sygnału można wyobrazić sobie jako efekt pomnożenia badanego sygnału przez okno. Ta operacja mnożenia w dziedzinie czasu, w dziedzinie częstości odpowiada splotowi widma sygnału z widmem okna. Aby uzyskać sygnał o skończonej długości odrzucamy wyzerowane odcinki. FFT widzi taki skończony odcinek jako  [[%C4%86wiczenia_2#Przed.C5.82u.C5.BCenie_przez_periodyczn.C4.85_replikacj.C4.99|periodyczne przedłużenie]].  Widać, że w praktyce estymowania widma zawsze mamy  do czynienia z widmami będącymi splotem widma sygnału i widma okna, ponieważ zawsze pracujemy z sygnałami o skończonej długości.&lt;br /&gt;
&lt;br /&gt;
===Zastosowania===&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	zamiana splotu na mnożenie&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	daje wgląd w okienkowanie&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	łatwo zrozumieć działanie filtrów&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Okienka==&lt;br /&gt;
===Wstęp===&lt;br /&gt;
* Jakie są dostępne okna w scipy.signal? Proszę odwiedzić stronę z [http://docs.scipy.org/doc/scipy-0.14.0/reference/signal.html dokumentacją].&lt;br /&gt;
* Jak wyglądają te okienka?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
from scipy import signal&lt;br /&gt;
w = signal.bartlett(10)&lt;br /&gt;
print(w)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Badanie własności okien===&lt;br /&gt;
&lt;br /&gt;
* Wykreśl okienko Bartletta o długości 100 i 101 próbek.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as py&lt;br /&gt;
&lt;br /&gt;
window = np.bartlett(101)&lt;br /&gt;
py.plot(window)&lt;br /&gt;
py.title(&amp;quot;okno Bartletta&amp;quot;)&lt;br /&gt;
py.ylabel(&amp;quot;Amplituda&amp;quot;)&lt;br /&gt;
py.xlabel(u&amp;quot;próbki&amp;quot;)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Proszę wykreślić widmo amplitudowe okna Bartletta o długości 101 próbek w skali [[wikipl:Decybel|dB]] (&amp;lt;tt&amp;gt;20*np.log10(.)&amp;lt;/tt&amp;gt;), raz korzystając z fft o naturalnej długości okna &amp;lt;tt&amp;gt;W = fft(okno)&amp;lt;/tt&amp;gt;, a drugi raz korzystając z przedłużenia zerami (w tym przypadku dostaniemy interpolowaną wersję widma) &amp;lt;tt&amp;gt;W = fft(okno, 2048)&amp;lt;/tt&amp;gt;. Proszę zwrócić uwagę na charakterystyczne elementy: szerokość piku głównego, szybkość zanikania listków bocznych, zera. &lt;br /&gt;
&lt;br /&gt;
Przydatna może być tu funkcja do obliczania widma (proszę przeanalizować kod i w razie wątpliwości poprosić o objaśnienie):&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1.0/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 *&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import fft, fftshift&lt;br /&gt;
import matplotlib.pyplot as py&lt;br /&gt;
&lt;br /&gt;
window = np.bartlett(51)&lt;br /&gt;
&lt;br /&gt;
W = fft(window)/len(window)&lt;br /&gt;
# rysować będziemy w skali logarytmicznej&lt;br /&gt;
widmo = abs(fftshift(W))&lt;br /&gt;
widmo_dB = 20*np.log10(widmo)&lt;br /&gt;
f = np.linspace(-0.5,0.5,len(W))&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(f,widmo_dB)&lt;br /&gt;
py.axis('tight')&lt;br /&gt;
&lt;br /&gt;
W_zeropadded = fft(window, 2048) / len(window)&lt;br /&gt;
widmo_zeropadded = abs(fftshift(W_zeropadded))&lt;br /&gt;
f = np.linspace(-0.5,0.5,len(W_zeropadded))&lt;br /&gt;
widmo_dB_zeropadded = 20*np.log10(widmo_zeropadded)&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(f ,widmo_dB_zeropadded)&lt;br /&gt;
py.title(&amp;quot;widmo okna Bartletta&amp;quot;)&lt;br /&gt;
py.ylabel(u&amp;quot;Wartość [dB]&amp;quot;)&lt;br /&gt;
py.xlabel(u&amp;quot;znormalizowana częstość&amp;quot;)&lt;br /&gt;
py.axis('tight')&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* A jakie własności ma okno prostokątne? Najprościej można je zrobić tak: &amp;lt;tt&amp;gt;window = np.ones(N)&amp;lt;/tt&amp;gt;. Proszę wykonać analogiczne rysunki jak dla okna Bartletta.&lt;br /&gt;
&lt;br /&gt;
* Proszę porównać przebiegi czasowe i własności widmowe pozostałych okien dostępnych w numpy, tzn.: &lt;br /&gt;
**blackman(M) 	&lt;br /&gt;
**hamming(M) 	&lt;br /&gt;
**hanning(M) 	&lt;br /&gt;
**kaiser(M, beta)&lt;br /&gt;
&lt;br /&gt;
===Własności okien w działaniu===&lt;br /&gt;
==== Okienko i szerokość prążka w widmie ====&lt;br /&gt;
* Wygeneruj sinusoidę o częstości &amp;lt;math&amp;gt;f=10.2&amp;lt;/math&amp;gt; Hz fazie 0, czasie trwania &amp;lt;math&amp;gt;T=1&amp;lt;/math&amp;gt; s, i częstości próbkowania &amp;lt;math&amp;gt;Fs=100&amp;lt;/math&amp;gt; Hz&lt;br /&gt;
* Wygeneruj okno prostokątne o długości równej długości sinusoidy.&lt;br /&gt;
* Zokienkuj sygnał mnożąc sinusoidę przez okienko&lt;br /&gt;
* Wykreśl zokienkowany sygnał, widmo zokienkowanego sygnału, widmo okienka&lt;br /&gt;
* Powtórz powyższe kroki dla okienek Bartletta, Hanna, Hamminga i Blackmana. Przy wykreślaniu widma zokienkowanego sygnału ustal zakres osi pionowej na [-50 10] (zastosuj &amp;lt;tt&amp;gt;py.ylim((-50,10)&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
* Proszę porównać widma otrzymane dla poszczególnych typów okienek.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 10.2, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,1)&lt;br /&gt;
okno = np.ones(len(x))/np.sqrt(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany prostokątem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,2)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego prostokątem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,3)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo prostokąta')&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,4)&lt;br /&gt;
okno = np.blackman(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Blackmanem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,5)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Blackmanem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,6)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Blackmana')&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,7)&lt;br /&gt;
okno = np.hamming(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Hamming')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,8)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Hamming')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,9)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Hamming')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
====Wpływ okienkowania na wykrywalność składowych o różnej amplitudzie ====&lt;br /&gt;
* Wygeneruj sygnał będący sumą dwóch sinusoid o fazie 0, czasie trwania &amp;lt;math&amp;gt;T=1&amp;lt;/math&amp;gt; s, i częstości próbkowania &amp;lt;math&amp;gt;Fs=100&amp;lt;/math&amp;gt; Hz. Jedna niech ma częstość &amp;lt;math&amp;gt;f=10.2&amp;lt;/math&amp;gt; Hz. Częstość drugiej, w kolejnych zapuszczeniach skryptu proszę zmieniać od 11,4 do 16,4 Hz z krokiem co 0,5 Hz.&lt;br /&gt;
* Jaki jest wpływ okienek na możliwości rozróżnienia dwóch częstości?&lt;br /&gt;
* Proszę powtórzyć iteracje dla przypadku gdy druga z sinusoid ma 10-krotnie niższą amplitudę.&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source  lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x1,t) = sin(f = 10.2, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
&lt;br /&gt;
(x2,t) = sin(f = 11.4+0.5*1, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
x = x1 + 1*x2 #0.1*&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,1)&lt;br /&gt;
okno = np.ones(len(x))/np.sqrt(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany prostokątem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,2)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego prostokątem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,3)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo prostokąta')&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,4)&lt;br /&gt;
okno = np.blackman(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Blackmanem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,5)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Blackmanem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,6)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Blackmana')&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,7)&lt;br /&gt;
okno = np.hamming(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Hamming')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,8)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Hamming')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,9)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Hamming')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Okienkować możemy też w częstości===&lt;br /&gt;
&lt;br /&gt;
* Proszę wykreślić widmo, a następie obliczyć i wykreślić [[%C4%86wiczenia_2#Transformaty_rzeczywiste_i_Hermitowskie|odwrotną transformatę Fouriera dla sygnału rzeczywistego]] zadanego w dziedzinie częstości przez (poniższy kod definiuje sygnał w dodatniej części widma):&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
S = np.zeros(128)&lt;br /&gt;
S[21] = 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Proszę wykreślić okienko prostokątne w częstości, pozycja 1 w binach częstości od 21 do 30, a następnie wykreślić odpowiadający mu sygnał w dziedzinie czasu.&lt;br /&gt;
&lt;br /&gt;
* Koncepcyjnie najprostszym filtrem jest operacja przemnożenia widma sygnału przez okienko w dziedzinie częstości a następnie zastosowanie odwrotnej transformaty Fouriera. Co stanie się z sygnałem w dziedzinie czasu, a co w dziedzinie częstości, jeśli chcielibyśmy przefiltrować go pasmowo przy użyciu filtra pasmowo przepustowego z poprzedniego punktu?&lt;br /&gt;
 * &amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  irfft,fftshift&lt;br /&gt;
 &lt;br /&gt;
S= np.zeros(128)&lt;br /&gt;
S[21:28] = 1&lt;br /&gt;
&lt;br /&gt;
s = fftshift(irfft(S))&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
F = range(len(S))&lt;br /&gt;
py.stem(F,S)&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
t = range(len(s))&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Porównajmy działanie najprostszych filtrów fft na biały szum.&lt;br /&gt;
** Proszę wytworzyć sygnał będący białym szumem o długości 256 próbek.&lt;br /&gt;
** Policz transformatę rzeczywistą tego sygnału.&lt;br /&gt;
** Przygotuj dwa okna w dziedzinie częstości (w części dodatniej)  o długości 129: &lt;br /&gt;
*** okno prostokątne  z jedynkami w punktach 20:30&lt;br /&gt;
*** okno Gaussowskie &amp;lt;tt&amp;gt;np.exp(-((F-25.0)/5)**2)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Przemnóż widmo sygnału przez każde z okien i oblicz odwrotną transformatę Fouriera. &lt;br /&gt;
** Zilustruj wyniki rysunkiem opisanym przez poniższą tabelkę:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|border = 1&lt;br /&gt;
|okno prostokątne w częstości &lt;br /&gt;
| okno Gaussowskie w częstości&lt;br /&gt;
|-&lt;br /&gt;
|przebieg czasowy odwrotnej tr. Fouriera okna Prostokątnego &lt;br /&gt;
|przebieg czasowy odwrotnej tr. Fouriera okna Gaussowskiego&lt;br /&gt;
|-&lt;br /&gt;
|przebieg czasowy szumu&lt;br /&gt;
|przebieg czasowy szumu&lt;br /&gt;
|-&lt;br /&gt;
|Przebieg czasowy odwrotnej tr. Fouriera iloczynu widma szumu i okna prostokątnego&lt;br /&gt;
|Przebieg czasowy odwrotnej tr. Fouriera iloczynu widma szumu i okna Gaussowskiego&lt;br /&gt;
|}&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  irfft,rfft,fftshift&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
szum = np.random.randn(128*2-2)&lt;br /&gt;
SZum = rfft(szum)&lt;br /&gt;
&lt;br /&gt;
S_prost= np.zeros(128)&lt;br /&gt;
S_prost[20:30]=1&lt;br /&gt;
s_prost = fftshift(irfft(S_prost))&lt;br /&gt;
&lt;br /&gt;
t = np.arange(len(s_prost))&lt;br /&gt;
F = np.arange(len(S_prost))&lt;br /&gt;
S_gauss = np.exp(-((F-25.0)/5)**2)&lt;br /&gt;
s_gauss = fftshift(irfft(S_gauss))&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,1)&lt;br /&gt;
py.stem(F,S_prost)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,3)&lt;br /&gt;
py.plot(t,s_prost)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,5)&lt;br /&gt;
py.plot(t,szum)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,7)&lt;br /&gt;
filtrowanySygnal = fftshift(irfft(SZum*S_prost))&lt;br /&gt;
py.plot(filtrowanySygnal)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,2)&lt;br /&gt;
py.stem(F,S_gauss)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,4)&lt;br /&gt;
py.plot(t,s_gauss)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,6)&lt;br /&gt;
py.plot(t,szum)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,8)&lt;br /&gt;
filtrowanySignal = fftshift(irfft(SZum*S_gauss))&lt;br /&gt;
py.plot(filtrowanySignal)&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=Analiza_sygna%C5%82%C3%B3w_-_%C4%87wiczenia&amp;diff=4241</id>
		<title>Analiza sygnałów - ćwiczenia</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=Analiza_sygna%C5%82%C3%B3w_-_%C4%87wiczenia&amp;diff=4241"/>
		<updated>2015-10-05T09:11:35Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Przedmioty specjalizacyjne]]&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
#[[Systemy liniowe niezmiennicze w czasie | Systemy liniowe niezmiennicze w czasie]]&lt;br /&gt;
[[Ćwiczenia 8|Filtrowanie obrazów]]&lt;br /&gt;
[[Ćwiczenia 9|Analiza czas-częstość]]&lt;br /&gt;
[[Ćwiczenia 10|Analiza czas-częstość &amp;amp;mdash; STFT i transformata falkowa]]&lt;br /&gt;
[[Ćwiczenia 11|Analiza czas-częstość &amp;amp;mdash; reprezentacje energetyczne]]&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[ZasadyZaliczenia|Zasady zaliczenia ćwiczeń]]&lt;br /&gt;
&lt;br /&gt;
#[[Ćwiczenia 1|Sygnały]] &amp;lt;!-- -- wstęp, generacja sygnaów testowych, aliasing, przypomnienie Pythona, wprowadzenie Svaroga; jak wczytać do Svaroga z Pythona i w drugą stronę --&amp;gt;&lt;br /&gt;
#[[Ćwiczenia 2|Transformata Fouriera]] i [[Ćwiczenia 2_2|Transformata Fouriera cd]] &amp;lt;!-- piszemy w Pythonie, porównujemy ze Svarogiem --&amp;gt;&lt;br /&gt;
#[[Ćwiczenia 3|Okienkowanie sygnału i transformata Fouriera]], [[Nieparametryczne widmo mocy |Estymacja widma mocy w oparciu o transformatę Fouriera]] &amp;lt;!-- widmo średniej vs. średnie widmo --&amp;gt;&lt;br /&gt;
#[[Ćwiczenia 6|Filtry I]] &amp;lt;!-- w Pythonie i w Svarogu --&amp;gt;&lt;br /&gt;
#[[Ćwiczenia 7|Filtry II]] &amp;lt;!-- oglądanie charakterystyk filtrów, ogładanie widma sygnałów przefiltrowanych, efektywność filtrów, przesuwanie fazy --&amp;gt;&lt;br /&gt;
#[[Ćwiczenia 4|Funkcja autokorelacji i procesy AR]]&lt;br /&gt;
#[[Ćwiczenia 5|Procesy AR]] &amp;lt;!-- AR w Pyhonie + DTF w Svarogu (MK) --&amp;gt;&lt;br /&gt;
#[[AS cwiczenia ICA| ICA]] &amp;lt;!-- montaże, ICA --&amp;gt;&lt;br /&gt;
#[[AS cwiczeniaTF|Metody czas-częstość]] &amp;lt;!-- STFT i falki --&amp;gt;&lt;br /&gt;
#[[AS cwiczeniaMP|Matching pursuit]] &amp;lt;!-- MP w Svarogu, zabawa parametrami dekompozycji, zabawa filtrowaniem map w Svarogu, postprocessing w Pythonie --&amp;gt;&lt;br /&gt;
# Uśrednianie gęstości energii vs gęstość energii uśrednionego sygnału: symulacje, ERD/S&lt;br /&gt;
#[[Ćwiczenia UNIFIKACJA]] &amp;lt;!-- ostatnie ćwiczenia na ktrych porównujemy na tych samych sygnałach rzeczywistych i symulowanych działanie różnych metod -- MMP vs DTF vs ICA, STFT vs WT vs MP itp, potrzebne fajne przykłady --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
autor dr Jarosław Żygierewicz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== INFORMACJE DODATKOWE ==&lt;br /&gt;
Materiały 2014/2015&lt;br /&gt;
# [[kolokwia2013_2014|Informacje o zaliczeniu ćwiczeń]] &lt;br /&gt;
# [[kolokwia2014_2015_kol1|Zagadnienia przygotowawcze do 1 kolokwium]] &lt;br /&gt;
# [[Projekt2014|Projekt zaliczeniowy]]&lt;br /&gt;
&lt;br /&gt;
Materiały 2013/2014&lt;br /&gt;
# [[Plik:Zadania_powtorzeniowe.pdf|Zadania powtorzeniowe do 2 kolokwium]]&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_1&amp;diff=4165</id>
		<title>Ćwiczenia 1</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_1&amp;diff=4165"/>
		<updated>2015-10-01T18:00:06Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Zadanie: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dokumentacja modułu scipy.signal ==&lt;br /&gt;
Proszę zapoznać się z dokumentacją biblioteki scipy.signal:&lt;br /&gt;
&lt;br /&gt;
http://docs.scipy.org/doc/scipy-0.14.0/reference/signal.html&lt;br /&gt;
&lt;br /&gt;
==Sygnały ciągłe i dyskretne ==&lt;br /&gt;
===Próbkowanie w czasie ===&lt;br /&gt;
Proszę powtórzyć sobie pojęcia:&lt;br /&gt;
* częstość próbkowania&lt;br /&gt;
* częstość Nyquista&lt;br /&gt;
* aliasing&lt;br /&gt;
&lt;br /&gt;
W poniższym ćwiczeniu chcemy zbadać efekt próbkowania sygnału w czasie. W komputerach nie mamy dostępu do sygnału ciągłego. Na nasze potrzeby wygenerujemy sygnały próbkowane z bardzo dużą częstością, które będą dla nas aproksymacją sygnałów ciągłych. Przy ich pomocy zaprezentujemy efekt utożsamiania (aliasingu).&lt;br /&gt;
&lt;br /&gt;
Proszę wytworzyć wektor reprezentujący czas &amp;amp;bdquo;prawie&amp;amp;rdquo; ciągły. Będzie to u nas 1000 wartości z przedziału [0,1) wziętych z odstępem 0,001.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
t = np.arange(0,1,0.001) # czas 'prawie ciągły'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Teraz proszę wygenerować dwie sinusoidy: jedną o częstości &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; a drugą o częstości &amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt;. Dla przypomnienia wyrażenie:&lt;br /&gt;
:&amp;lt;math&amp;gt; s(t) = \sin(2 \pi f t)&amp;lt;/math&amp;gt; możemy w pythonie zapisać:&lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
s = np.sin(2*np.pi*f*t)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Proszę [[TI/Matplotlib#Kilka_wykres.C3.B3w_we_wsp.C3.B3lnych_osiach|wykreślić]] obie sinusoidy.&lt;br /&gt;
&lt;br /&gt;
Teraz proszę spróbkować czas i nasze &amp;amp;bdquo;prawie&amp;amp;rdquo; ciągłe sinusoidy z okresem próbkowania 0,1. (Trzeba pobrać co 100 element, proszę posłużyć się [[Programowanie_z_Pythonem/Sekwencje#Wycinki|wycinkami]]) &amp;lt;!-- [[TI/Sekwencje|Struktury danych — sekwencje|wycinkami]]. --&amp;gt;&lt;br /&gt;
Na tle &amp;amp;bdquo;prawie&amp;amp;rdquo; ciągłych sinusoid proszę dorysować punkty ze spróbkowanych sygnałów. Aby punkty były dobrze  widoczne proponuję użyć markerów &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; oraz &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Proszę zaobserwować wzajemne położenie punktów. Czy można odróżnić sinusoidę o częstości &amp;amp;minus;1 od sinusoidy o częstości 9, jeśli obie są próbkowane z częstością 10? Jak można uogólnić tą obserwację?&lt;br /&gt;
  &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
t = np.arange(0,1,0.001) # czas 'prawie ciągły'&lt;br /&gt;
f1 = -1 # częstość sygnału 1&lt;br /&gt;
f2 = 9 # częstość sygnału 2&lt;br /&gt;
s1 = np.sin(2*np.pi*f1*t) # prawie ciągły sygnał o częstości f1&lt;br /&gt;
s2 = np.sin(2*np.pi*f2*t) # prawie ciągły sygnał o częstości f2&lt;br /&gt;
&lt;br /&gt;
T = 0.1 # okres próbkowania&lt;br /&gt;
Fs = 1/T # częstość próbkowania&lt;br /&gt;
FN = Fs/2 # częstość Nyquista&lt;br /&gt;
T_samp = t[0::100] # czas pobierania próbek&lt;br /&gt;
s1_samp = s1[0::100] # próbkowany sygnał o częstości f1&lt;br /&gt;
s2_samp = s2[0::100] # próbkowany sygnał o częstości f2&lt;br /&gt;
&lt;br /&gt;
py.plot(t, s1, 'g')&lt;br /&gt;
py.plot(t, s2, 'b')&lt;br /&gt;
py.plot(T_samp, s1_samp, 'gx', markersize=10)&lt;br /&gt;
py.plot(T_samp, s2_samp, 'r+', markersize=10)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===Błąd kwantyzacji ===&lt;br /&gt;
Kiedy mierzymy fizyczne wielkości w celu dalszej analizy najczęściej chcemy przypisać im pewne liczby. Liczby w systemach cyfrowych reprezentowane są ze skończoną dokładnością. Urządzenia dokonujące przypisania liczby do mierzonej wartości to przetworniki analogowo-cyfrowe (ang. ADC, Analog to Digital Converter).&lt;br /&gt;
Charakteryzują się one określoną ilością bitów ''N'', za pomocą których reprezentują liczby. Pełen zakres wartości pomiarowych ''R'' jest dzielony na &amp;lt;math&amp;gt;2^N&amp;lt;/math&amp;gt; poziomów. Błąd kwantyzacji szacujemy jako nie większy niż &amp;lt;math&amp;gt; \frac{R}{2^{N+1}} &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
====Zadanie:====&lt;br /&gt;
Proszę oszacować błąd kwantyzacji sygnału EEG mierzonego za pomocą 12-bitowego konwertera. Zakres pomiarowy tego urządzenia to &amp;amp;plusmn;200 &amp;amp;mu;V.&lt;br /&gt;
====Zadanie:====&lt;br /&gt;
Proszę zilustrować efekt kwantyzacji dla trzybitowego przetwornika o zakresie 2.&lt;br /&gt;
W tym celu proszę wykonać następujące kroki:&lt;br /&gt;
# wygenerować &amp;amp;bdquo;prawie&amp;amp;rdquo; ciągłą sinusoidę (częstość 1, czas trwania 1 próbkowanie co 0,001)&lt;br /&gt;
# spróbkować tą sinusoidę co 0,1 (proszę zastosować wycinki)&lt;br /&gt;
# proszę skwantować spróbkowane wartości &lt;br /&gt;
#Proszę wykreślić na jednym rysunku &lt;br /&gt;
#* oryginalny sygnał &lt;br /&gt;
#* sygnał spróbkowany w czasie&lt;br /&gt;
#* sygnał spróbkowany w czasie i o skwantowanej amplitudzie (skorzystać z funkcji &amp;lt;tt&amp;gt;py.step&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
{{ Wyjaśnienie|title= wskazówka: Kwantowanie | text = &lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
N_bits = 3&lt;br /&gt;
zakres = 2.0&lt;br /&gt;
dy = zakres/2**N_bits&lt;br /&gt;
s1_kwantowany = np.floor(s1_samp/dy)*dy +0.5*dy&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
t = np.arange(0,1,0.001) # czas 'prawie ciągły'&lt;br /&gt;
f1 = 1 # częstość sygnału 1&lt;br /&gt;
&lt;br /&gt;
s1 = np.sin(2*np.pi*f1*t) # prawie ciągły sygnał o częstości f1&lt;br /&gt;
T_samp = t[0::100]&lt;br /&gt;
s1_samp = s1[0::100]&lt;br /&gt;
&lt;br /&gt;
N_bits = 3&lt;br /&gt;
zakres = 2.0&lt;br /&gt;
dy = zakres/2**N_bits&lt;br /&gt;
s1_kwantowany = np.floor(s1_samp/dy)*dy +0.5*dy&lt;br /&gt;
ax = py.subplot(111)&lt;br /&gt;
py.plot(t,s1)&lt;br /&gt;
py.plot(T_samp,s1_samp,'ko',markersize = 5)&lt;br /&gt;
py.step(T_samp,s1_kwantowany,where = 'post')&lt;br /&gt;
&lt;br /&gt;
ax.set_xticks(T_samp)&lt;br /&gt;
poziomy = np.arange(-1+0.5*dy,1,dy)&lt;br /&gt;
ax.set_yticks(poziomy)&lt;br /&gt;
py.grid('on')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
for i in xrange(0,8):&lt;br /&gt;
	py.text(1.02,poziomy[i],bin(i))&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Sygnały testowe==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Generowanie sygnałów testowych ===&lt;br /&gt;
&lt;br /&gt;
Do badania różnych metod analizy sygnałów potrzebne nam będą sygnały o znanych własnościach. W szczególności dobrze jest umnieć nadać sygnałom występującym w postaci cyfrowej, oraz sztucznym sygnałom próbnym pewne własności fizyczne takie jak:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	czętość próbkowania&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	czas trwania&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	amplituda&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
=== Przykład sinus===&lt;br /&gt;
Sinus o zadanej częstości (w Hz), długości trwania, częstości próbkowania i fazie.&lt;br /&gt;
Poniższy kod implementuje i testuje funkcję &lt;br /&gt;
:&amp;lt;math&amp;gt; \sin(f,T,Fs,\phi) = \sin(2*\pi f t)&amp;lt;/math&amp;gt; dla &amp;lt;math&amp;gt;t \in \{0,T\}&amp;lt;/math&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang= python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1 Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
(s,t) = sin(f=10,Fs=1000)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
=== Przykład: eksport sygnału do pliku binarnego ===&lt;br /&gt;
* Poniższy kod ilustruje sposób zapisu dwóch funkcji sinus o częstościach 10 Hz i 21 Hz do pliku binarnego:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang= python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    T = 5&lt;br /&gt;
    Fs = 128.0&lt;br /&gt;
&lt;br /&gt;
    s1 = sin(f=10, T=T, Fs=Fs)&lt;br /&gt;
    s2 = sin(f=21, T=T, Fs=Fs)	&lt;br /&gt;
	&lt;br /&gt;
    signal = np.zeros((T*Fs, 2), dtype='&amp;lt;f')&lt;br /&gt;
    signal[:, 0] = s1&lt;br /&gt;
    signal[:, 1] = s2&lt;br /&gt;
&lt;br /&gt;
    with open('test_signal.bin', 'wb') as f:&lt;br /&gt;
        signal.tofile(f)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Przykład: wczytanie sygnału do Svaroga ===&lt;br /&gt;
W celu wczytania zapisanego binarnie sygnału do programu Svarog, po wybraniu File -&amp;gt; Open signal, należy wprowadzić częstość próbkowania sygnału oraz liczbę kanałów. &lt;br /&gt;
&lt;br /&gt;
[[Plik:svarog_open_signal.png|center|800px|thumb|&amp;lt;figure id=&amp;quot;uid3&amp;quot; /&amp;gt;Wczytywanie sygnału w programie Svarog.]]&lt;br /&gt;
&lt;br /&gt;
=== Delta ===&lt;br /&gt;
Podobnie można zdefiniować funkcję delta o zadanym czasie trwania, częstości próbkowania i momencie wystąpienia impulsu:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt; \delta(t_0) = \left\{^{1 \quad t=t_0} _{0 \quad t \ne t_0} \right.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang= python&amp;gt;&lt;br /&gt;
def delta(t0=0.5, T=1  ,Fs = 128):&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	d = np.zeros(len(t))&lt;br /&gt;
	d[np.ceil(t0*Fs)]=1&lt;br /&gt;
	return (d,t)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Zadanie:===&lt;br /&gt;
Analogicznie do powyższych przykładów proszę zaimplementować i przetestować funkcje generujące:&lt;br /&gt;
* funkcję Gabora (funkcja Gaussa modulowana cosinusem) o zadanej częstości i standardowym odchyleniu w czasie, momencie wystąpienia, długości, częstości próbkowania i fazie. &lt;br /&gt;
:&amp;lt;math&amp;gt; g = \exp\left(-\frac{1}{2}\left(\frac{t-t_0}{\sigma}\right)^2 \right) \cdot  \cos(2 \pi f t + \phi); &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* szum gaussowski o zadanej średniej, odchyleniu standardowym, długości i częstości próbkowania.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- * pochodną funkcji Gaussa&lt;br /&gt;
&lt;br /&gt;
* połówkę funkcji Gaussa&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_1&amp;diff=4151</id>
		<title>Ćwiczenia 1</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_1&amp;diff=4151"/>
		<updated>2015-09-30T14:12:02Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Przykład: eksport sygnału do pliku binarnego */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dokumentacja modułu scipy.signal ==&lt;br /&gt;
Proszę zapoznać się z dokumentacją biblioteki scipy.signal:&lt;br /&gt;
&lt;br /&gt;
http://docs.scipy.org/doc/scipy-0.14.0/reference/signal.html&lt;br /&gt;
&lt;br /&gt;
==Sygnały ciągłe i dyskretne ==&lt;br /&gt;
===Próbkowanie w czasie ===&lt;br /&gt;
Proszę powtórzyć sobie pojęcia:&lt;br /&gt;
* częstość próbkowania&lt;br /&gt;
* częstość Nyquista&lt;br /&gt;
* aliasing&lt;br /&gt;
&lt;br /&gt;
W poniższym ćwiczeniu chcemy zbadać efekt próbkowania sygnału w czasie. W komputerach nie mamy dostępu do sygnału ciągłego. Na nasze potrzeby wygenerujemy sygnały próbkowane z bardzo dużą częstością, które będą dla nas aproksymacją sygnałów ciągłych. Przy ich pomocy zaprezentujemy efekt utożsamiania (aliasingu).&lt;br /&gt;
&lt;br /&gt;
Proszę wytworzyć wektor reprezentujący czas &amp;amp;bdquo;prawie&amp;amp;rdquo; ciągły. Będzie to u nas 1000 wartości z przedziału [0,1) wziętych z odstępem 0,001.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
t = np.arange(0,1,0.001) # czas 'prawie ciągły'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Teraz proszę wygenerować dwie sinusoidy: jedną o częstości &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; a drugą o częstości &amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt;. Dla przypomnienia wyrażenie:&lt;br /&gt;
:&amp;lt;math&amp;gt; s(t) = \sin(2 \pi f t)&amp;lt;/math&amp;gt; możemy w pythonie zapisać:&lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
s = np.sin(2*np.pi*f*t)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Proszę [[TI/Matplotlib#Kilka_wykres.C3.B3w_we_wsp.C3.B3lnych_osiach|wykreślić]] obie sinusoidy.&lt;br /&gt;
&lt;br /&gt;
Teraz proszę spróbkować czas i nasze &amp;amp;bdquo;prawie&amp;amp;rdquo; ciągłe sinusoidy z okresem próbkowania 0,1. (Trzeba pobrać co 100 element, proszę posłużyć się [[Programowanie_z_Pythonem/Sekwencje#Wycinki|wycinkami]]) &amp;lt;!-- [[TI/Sekwencje|Struktury danych — sekwencje|wycinkami]]. --&amp;gt;&lt;br /&gt;
Na tle &amp;amp;bdquo;prawie&amp;amp;rdquo; ciągłych sinusoid proszę dorysować punkty ze spróbkowanych sygnałów. Aby punkty były dobrze  widoczne proponuję użyć markerów &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; oraz &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Proszę zaobserwować wzajemne położenie punktów. Czy można odróżnić sinusoidę o częstości &amp;amp;minus;1 od sinusoidy o częstości 9, jeśli obie są próbkowane z częstością 10? Jak można uogólnić tą obserwację?&lt;br /&gt;
  &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
t = np.arange(0,1,0.001) # czas 'prawie ciągły'&lt;br /&gt;
f1 = -1 # częstość sygnału 1&lt;br /&gt;
f2 = 9 # częstość sygnału 2&lt;br /&gt;
s1 = np.sin(2*np.pi*f1*t) # prawie ciągły sygnał o częstości f1&lt;br /&gt;
s2 = np.sin(2*np.pi*f2*t) # prawie ciągły sygnał o częstości f2&lt;br /&gt;
&lt;br /&gt;
T = 0.1 # okres próbkowania&lt;br /&gt;
Fs = 1/T # częstość próbkowania&lt;br /&gt;
FN = Fs/2 # częstość Nyquista&lt;br /&gt;
T_samp = t[0::100] # czas pobierania próbek&lt;br /&gt;
s1_samp = s1[0::100] # próbkowany sygnał o częstości f1&lt;br /&gt;
s2_samp = s2[0::100] # próbkowany sygnał o częstości f2&lt;br /&gt;
&lt;br /&gt;
py.plot(t, s1, 'g')&lt;br /&gt;
py.plot(t, s2, 'b')&lt;br /&gt;
py.plot(T_samp, s1_samp, 'gx', markersize=10)&lt;br /&gt;
py.plot(T_samp, s2_samp, 'r+', markersize=10)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===Błąd kwantyzacji ===&lt;br /&gt;
Kiedy mierzymy fizyczne wielkości w celu dalszej analizy najczęściej chcemy przypisać im pewne liczby. Liczby w systemach cyfrowych reprezentowane są ze skończoną dokładnością. Urządzenia dokonujące przypisania liczby do mierzonej wartości to przetworniki analogowo-cyfrowe (ang. ADC, Analog to Digital Converter).&lt;br /&gt;
Charakteryzują się one określoną ilością bitów ''N'', za pomocą których reprezentują liczby. Pełen zakres wartości pomiarowych ''R'' jest dzielony na &amp;lt;math&amp;gt;2^N&amp;lt;/math&amp;gt; poziomów. Błąd kwantyzacji szacujemy jako nie większy niż &amp;lt;math&amp;gt; \frac{R}{2^{N+1}} &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
====Zadanie:====&lt;br /&gt;
Proszę oszacować błąd kwantyzacji sygnału EEG mierzonego za pomocą 12-bitowego konwertera. Zakres pomiarowy tego urządzenia to &amp;amp;plusmn;200 &amp;amp;mu;V.&lt;br /&gt;
====Zadanie:====&lt;br /&gt;
Proszę zilustrować efekt kwantyzacji dla trzybitowego przetwornika o zakresie 2.&lt;br /&gt;
W tym celu proszę wykonać następujące kroki:&lt;br /&gt;
# wygenerować &amp;amp;bdquo;prawie&amp;amp;rdquo; ciągłą sinusoidę (częstość 1, czas trwania 1 próbkowanie co 0,001)&lt;br /&gt;
# spróbkować tą sinusoidę co 0,1 (proszę zastosować wycinki)&lt;br /&gt;
# proszę skwantować spróbkowane wartości &lt;br /&gt;
#Proszę wykreślić na jednym rysunku &lt;br /&gt;
#* oryginalny sygnał &lt;br /&gt;
#* sygnał spróbkowany w czasie&lt;br /&gt;
#* sygnał spróbkowany w czasie i o skwantowanej amplitudzie (skorzystać z funkcji &amp;lt;tt&amp;gt;py.step&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
{{ Wyjaśnienie|title= wskazówka: Kwantowanie | text = &lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
N_bits = 3&lt;br /&gt;
zakres = 2.0&lt;br /&gt;
dy = zakres/2**N_bits&lt;br /&gt;
s1_kwantowany = np.floor(s1_samp/dy)*dy +0.5*dy&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
t = np.arange(0,1,0.001) # czas 'prawie ciągły'&lt;br /&gt;
f1 = 1 # częstość sygnału 1&lt;br /&gt;
&lt;br /&gt;
s1 = np.sin(2*np.pi*f1*t) # prawie ciągły sygnał o częstości f1&lt;br /&gt;
T_samp = t[0::100]&lt;br /&gt;
s1_samp = s1[0::100]&lt;br /&gt;
&lt;br /&gt;
N_bits = 3&lt;br /&gt;
zakres = 2.0&lt;br /&gt;
dy = zakres/2**N_bits&lt;br /&gt;
s1_kwantowany = np.floor(s1_samp/dy)*dy +0.5*dy&lt;br /&gt;
ax = py.subplot(111)&lt;br /&gt;
py.plot(t,s1)&lt;br /&gt;
py.plot(T_samp,s1_samp,'ko',markersize = 5)&lt;br /&gt;
py.step(T_samp,s1_kwantowany,where = 'post')&lt;br /&gt;
&lt;br /&gt;
ax.set_xticks(T_samp)&lt;br /&gt;
poziomy = np.arange(-1+0.5*dy,1,dy)&lt;br /&gt;
ax.set_yticks(poziomy)&lt;br /&gt;
py.grid('on')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
for i in xrange(0,8):&lt;br /&gt;
	py.text(1.02,poziomy[i],bin(i))&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Sygnały testowe==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Generowanie sygnałów testowych ===&lt;br /&gt;
&lt;br /&gt;
Do badania różnych metod analizy sygnałów potrzebne nam będą sygnały o znanych własnościach. W szczególności dobrze jest umnieć nadać sygnałom występującym w postaci cyfrowej, oraz sztucznym sygnałom próbnym pewne własności fizyczne takie jak:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	czętość próbkowania&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	czas trwania&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	amplituda&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
=== Przykład sinus===&lt;br /&gt;
Sinus o zadanej częstości (w Hz), długości trwania, częstości próbkowania i fazie.&lt;br /&gt;
Poniższy kod implementuje i testuje funkcję &lt;br /&gt;
:&amp;lt;math&amp;gt; \sin(f,T,Fs,\phi) = \sin(2*\pi f t)&amp;lt;/math&amp;gt; dla &amp;lt;math&amp;gt;t \in \{0,T\}&amp;lt;/math&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang= python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1 Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
(s,t) = sin(f=10,Fs=1000)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
=== Przykład: eksport sygnału do pliku binarnego ===&lt;br /&gt;
* Poniższy kod ilustruje sposób zapisu dwóch funkcji sinus o częstościach 10 Hz i 21 Hz do pliku binarnego:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang= python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    T = 5&lt;br /&gt;
    Fs = 128.0&lt;br /&gt;
&lt;br /&gt;
    s1 = sin(f=10, T=T, Fs=Fs)&lt;br /&gt;
    s2 = sin(f=21, T=T, Fs=Fs)	&lt;br /&gt;
	&lt;br /&gt;
    signal = np.zeros((T*Fs, 2), dtype='&amp;lt;f')&lt;br /&gt;
    signal[:, 0] = s1&lt;br /&gt;
    signal[:, 1] = s2&lt;br /&gt;
&lt;br /&gt;
    with open('test_signal.bin', 'wb') as f:&lt;br /&gt;
        signal.tofile(f)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Przykład: wczytanie sygnału do Svaroga ===&lt;br /&gt;
W celu wczytania zapisanego binarnie sygnału do programu Svarog, po wybraniu File -&amp;gt; Open signal, należy wprowadzić częstość próbkowania sygnału oraz liczbę kanałów. &lt;br /&gt;
&lt;br /&gt;
[[Plik:svarog_open_signal.png|center|800px|thumb|&amp;lt;figure id=&amp;quot;uid3&amp;quot; /&amp;gt;Wczytywanie sygnału w programie Svarog.]]&lt;br /&gt;
&lt;br /&gt;
=== Delta ===&lt;br /&gt;
Podobnie można zdefiniować funkcję delta o zadanym czasie trwania, częstości próbkowania i momencie wystąpienia impulsu:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt; \delta(t_0) = \left\{^{1 \quad t=t_0} _{0 \quad t \ne t_0} \right.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang= python&amp;gt;&lt;br /&gt;
def delta(t0=0.5, T=1  ,Fs = 128):&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	d = np.zeros(len(t))&lt;br /&gt;
	d[np.ceil(t0*Fs)]=1&lt;br /&gt;
	return (d,t)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Zadanie:===&lt;br /&gt;
Analogicznie do powyższych przykładów proszę zaimplementować iprzetestować funkcje generujące:&lt;br /&gt;
* funkcję Gabora (funkcja Gaussa modulowana cosinusem) o zadanej częstości i standardowym odchyleniu w czasie, momencie wystąpienia, długości, częstości próbkowania i fazie. &lt;br /&gt;
:&amp;lt;math&amp;gt; g = \exp\left(-\frac{1}{2}\left(\frac{t-t_0}{\sigma}\right)^2 \right) \cdot  \cos(2 \pi f t + \phi); &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* szum gaussowski o zadanej średniej, odchyleniu standardowym, długości i częstości próbkowania.&lt;br /&gt;
&lt;br /&gt;
* pochodną funkcji Gaussa&lt;br /&gt;
&lt;br /&gt;
* połówkę funkcji Gaussa&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_3&amp;diff=4150</id>
		<title>Ćwiczenia 3</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_3&amp;diff=4150"/>
		<updated>2015-09-30T12:53:10Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Okienkować możemy też w częstości */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Twierdzenie o splocie ==&lt;br /&gt;
Na pierwszych ćwiczeniach poznaliśmy poznaliśmy operację [[Systemy_liniowe_niezmiennicze_w_czasie#Splot|splotu]] jako efekt działania systemu liniowego niezmienniczego w czasie. Poznaliśmy wówczas jego [[Systemy_liniowe_niezmiennicze_w_czasie#W.C5.82asno.C5.9Bci_splotu|własności]].&lt;br /&gt;
Okazuje się, że gdy rozważamy sprzężone ze sobą za pomocą transformaty Fouriera dziedziny czasu i częstości splot ma wiele wspólnego z mnożeniem. Związek ten można zapisać jako &lt;br /&gt;
[[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|Twierdzenie o splocie:]] &lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid2&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
g(t)=\left(s * h\right)(t)\quad \Rightarrow \quad G(f)=S(f)\cdot H(f)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
To twierdzenie działa też w drugą stronę:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
G(f)=\left(S * H\right)(f)\quad \Rightarrow \quad g(t)=s(t)\cdot h(t)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W praktyce oznacza to tyle, że jeśli w jednej dziedzinie jakieś dwa sygnały przez siebie przemnożymy, to w drugiej dziedzinie transformaty tych sygnałów splatają się. Własność ta ma bardzo ważne konsekwencje, np. przy estymacji widma skończonego fragmentu sygnału. Dlaczego?&lt;br /&gt;
&lt;br /&gt;
Wyobraźmy sobie, że mamy nieskończenie długi sygnał. Oprócz niego mamy też funkcję, która jest niezerowa tylko na skończonym odcinku. Funkcję taką będziemy nazywać oknem. Pobranie fragmentu sygnału można wyobrazić sobie jako efekt pomnożenia badanego sygnału przez okno. Ta operacja mnożenia w dziedzinie czasu, w dziedzinie częstości odpowiada splotowi widma sygnału z widmem okna. Aby uzyskać sygnał o skończonej długości odrzucamy wyzerowane odcinki. FFT widzi taki skończony odcinek jako  [[%C4%86wiczenia_2#Przed.C5.82u.C5.BCenie_przez_periodyczn.C4.85_replikacj.C4.99|periodyczne przedłużenie]].  Widać, że w praktyce estymowania widma zawsze mamy  do czynienia z widmami będącymi splotem widma sygnału i widma okna, ponieważ zawsze pracujemy z sygnałami o skończonej długości.&lt;br /&gt;
&lt;br /&gt;
===Zastosowania===&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	zamiana splotu na mnożenie&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	daje wgląd w okienkowanie&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	łatwo zrozumieć działanie filtrów&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Okienka==&lt;br /&gt;
===Wstęp===&lt;br /&gt;
* Jakie są dostępne okna w Numpy? Proszę odwiedzić stronę z [http://docs.scipy.org/doc/numpy/reference/routines.window.html dokumentacją].&lt;br /&gt;
* Jak wyglądają te okienka?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
w = np.bartlett(10)&lt;br /&gt;
print w&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Badanie własności okien===&lt;br /&gt;
&lt;br /&gt;
* Wykreśl okienko Bartletta o długości 100 i 101 próbek.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as py&lt;br /&gt;
&lt;br /&gt;
window = np.bartlett(101)&lt;br /&gt;
py.plot(window)&lt;br /&gt;
py.title(&amp;quot;okno Bartletta&amp;quot;)&lt;br /&gt;
py.ylabel(&amp;quot;Amplituda&amp;quot;)&lt;br /&gt;
py.xlabel(u&amp;quot;próbki&amp;quot;)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Proszę wykreślić widmo amplitudowe okna Bartletta o długości 101 próbek w skali [[wikipl:Decybel|dB]] (&amp;lt;tt&amp;gt;20*np.log10(.)&amp;lt;/tt&amp;gt;), raz korzystając z fft o naturalnej długości okna &amp;lt;tt&amp;gt;W = fft(okno)&amp;lt;/tt&amp;gt;, a drugi raz korzystając z przedłużenia zerami (w tym przypadku dostaniemy interpolowaną wersję widma) &amp;lt;tt&amp;gt;W = fft(okno, 2048)&amp;lt;/tt&amp;gt;. Proszę zwrócić uwagę na charakterystyczne elementy: szerokość piku głównego, szybkość zanikania listków bocznych, zera. &lt;br /&gt;
&lt;br /&gt;
Przydatna może być tu funkcja do obliczania widma (proszę przeanalizować kod i w razie wątpliwości poprosić o objaśnienie):&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1.0/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 *&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import fft, fftshift&lt;br /&gt;
import matplotlib.pyplot as py&lt;br /&gt;
&lt;br /&gt;
window = np.bartlett(51)&lt;br /&gt;
&lt;br /&gt;
W = fft(window)/len(window)&lt;br /&gt;
# rysować będziemy w skali logarytmicznej&lt;br /&gt;
widmo = abs(fftshift(W))&lt;br /&gt;
widmo_dB = 20*np.log10(widmo)&lt;br /&gt;
f = np.linspace(-0.5,0.5,len(W))&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(f,widmo_dB)&lt;br /&gt;
py.axis('tight')&lt;br /&gt;
&lt;br /&gt;
W_zeropadded = fft(window, 2048) / len(window)&lt;br /&gt;
widmo_zeropadded = abs(fftshift(W_zeropadded))&lt;br /&gt;
f = np.linspace(-0.5,0.5,len(W_zeropadded))&lt;br /&gt;
widmo_dB_zeropadded = 20*np.log10(widmo_zeropadded)&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(f ,widmo_dB_zeropadded)&lt;br /&gt;
py.title(&amp;quot;widmo okna Bartletta&amp;quot;)&lt;br /&gt;
py.ylabel(u&amp;quot;Wartość [dB]&amp;quot;)&lt;br /&gt;
py.xlabel(u&amp;quot;znormalizowana częstość&amp;quot;)&lt;br /&gt;
py.axis('tight')&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* A jakie własności ma okno prostokątne? Najprościej można je zrobić tak: &amp;lt;tt&amp;gt;window = np.ones(N)&amp;lt;/tt&amp;gt;. Proszę wykonać analogiczne rysunki jak dla okna Bartletta.&lt;br /&gt;
&lt;br /&gt;
* Proszę porównać przebiegi czasowe i własności widmowe pozostałych okien dostępnych w numpy, tzn.: &lt;br /&gt;
**blackman(M) 	&lt;br /&gt;
**hamming(M) 	&lt;br /&gt;
**hanning(M) 	&lt;br /&gt;
**kaiser(M, beta)&lt;br /&gt;
&lt;br /&gt;
===Własności okien w działaniu===&lt;br /&gt;
==== Okienko i szerokość prążka w widmie ====&lt;br /&gt;
* Wygeneruj sinusoidę o częstości &amp;lt;math&amp;gt;f=10.2&amp;lt;/math&amp;gt; Hz fazie 0, czasie trwania &amp;lt;math&amp;gt;T=1&amp;lt;/math&amp;gt; s, i częstości próbkowania &amp;lt;math&amp;gt;Fs=100&amp;lt;/math&amp;gt; Hz&lt;br /&gt;
* Wygeneruj okno prostokątne o długości równej długości sinusoidy.&lt;br /&gt;
* Zokienkuj sygnał mnożąc sinusoidę przez okienko&lt;br /&gt;
* Wykreśl zokienkowany sygnał, widmo zokienkowanego sygnału, widmo okienka&lt;br /&gt;
* Powtórz powyższe kroki dla okienek Bartletta, Hanna, Hamminga i Blackmana. Przy wykreślaniu widma zokienkowanego sygnału ustal zakres osi pionowej na [-50 10] (zastosuj &amp;lt;tt&amp;gt;py.ylim((-50,10)&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
* Proszę porównać widma otrzymane dla poszczególnych typów okienek.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 10.2, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,1)&lt;br /&gt;
okno = np.ones(len(x))/np.sqrt(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany prostokątem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,2)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego prostokątem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,3)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo prostokąta')&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,4)&lt;br /&gt;
okno = np.blackman(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Blackmanem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,5)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Blackmanem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,6)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Blackmana')&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,7)&lt;br /&gt;
okno = np.hamming(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Hamming')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,8)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Hamming')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,9)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Hamming')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
====Wpływ okienkowania na wykrywalność składowych o różnej amplitudzie ====&lt;br /&gt;
* Wygeneruj sygnał będący sumą dwóch sinusoid o fazie 0, czasie trwania &amp;lt;math&amp;gt;T=1&amp;lt;/math&amp;gt; s, i częstości próbkowania &amp;lt;math&amp;gt;Fs=100&amp;lt;/math&amp;gt; Hz. Jedna niech ma częstość &amp;lt;math&amp;gt;f=10.2&amp;lt;/math&amp;gt; Hz. Częstość drugiej, w kolejnych zapuszczeniach skryptu proszę zmieniać od 11,4 do 16,4 Hz z krokiem co 0,5 Hz.&lt;br /&gt;
* Jaki jest wpływ okienek na możliwości rozróżnienia dwóch częstości?&lt;br /&gt;
* Proszę powtórzyć iteracje dla przypadku gdy druga z sinusoid ma 10-krotnie niższą amplitudę.&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source  lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x1,t) = sin(f = 10.2, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
&lt;br /&gt;
(x2,t) = sin(f = 11.4+0.5*1, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
x = x1 + 1*x2 #0.1*&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,1)&lt;br /&gt;
okno = np.ones(len(x))/np.sqrt(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany prostokątem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,2)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego prostokątem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,3)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo prostokąta')&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,4)&lt;br /&gt;
okno = np.blackman(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Blackmanem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,5)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Blackmanem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,6)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Blackmana')&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,7)&lt;br /&gt;
okno = np.hamming(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Hamming')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,8)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Hamming')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,9)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Hamming')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Okienkować możemy też w częstości===&lt;br /&gt;
&lt;br /&gt;
* Proszę wykreślić widmo, a następie obliczyć i wykreślić [[%C4%86wiczenia_2#Transformaty_rzeczywiste_i_Hermitowskie|odwrotną transformatę Fouriera dla sygnału rzeczywistego]] zadanego w dziedzinie częstości przez (poniższy kod definiuje sygnał w dodatniej części widma):&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
S = np.zeros(128)&lt;br /&gt;
S[21] = 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Proszę wykreślić okienko prostokątne w częstości, pozycja 1 w binach częstości od 21 do 30, a następnie wykreślić odpowiadający mu sygnał w dziedzinie czasu.&lt;br /&gt;
&lt;br /&gt;
* Koncepcyjnie najprostszym filtrem jest operacja przemnożenia widma sygnału przez okienko w dziedzinie częstości a następnie zastosowanie odwrotnej transformaty Fouriera. Co stanie się z sygnałem w dziedzinie czasu, a co w dziedzinie częstości, jeśli chcielibyśmy przefiltrować go pasmowo przy użyciu filtra pasmowo przepustowego z poprzedniego punktu?&lt;br /&gt;
 * &amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  irfft,fftshift&lt;br /&gt;
 &lt;br /&gt;
S= np.zeros(128)&lt;br /&gt;
S[21:28] = 1&lt;br /&gt;
&lt;br /&gt;
s = fftshift(irfft(S))&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
F = range(len(S))&lt;br /&gt;
py.stem(F,S)&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
t = range(len(s))&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Porównajmy działanie najprostszych filtrów fft na biały szum.&lt;br /&gt;
** Proszę wytworzyć sygnał będący białym szumem o długości 256 próbek.&lt;br /&gt;
** Policz transformatę rzeczywistą tego sygnału.&lt;br /&gt;
** Przygotuj dwa okna w dziedzinie częstości (w części dodatniej)  o długości 129: &lt;br /&gt;
*** okno prostokątne  z jedynkami w punktach 20:30&lt;br /&gt;
*** okno Gaussowskie &amp;lt;tt&amp;gt;np.exp(-((F-25.0)/5)**2)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Przemnóż widmo sygnału przez każde z okien i oblicz odwrotną transformatę Fouriera. &lt;br /&gt;
** Zilustruj wyniki rysunkiem opisanym przez poniższą tabelkę:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|border = 1&lt;br /&gt;
|okno prostokątne w częstości &lt;br /&gt;
| okno Gaussowskie w częstości&lt;br /&gt;
|-&lt;br /&gt;
|przebieg czasowy odwrotnej tr. Fouriera okna Prostokątnego &lt;br /&gt;
|przebieg czasowy odwrotnej tr. Fouriera okna Gaussowskiego&lt;br /&gt;
|-&lt;br /&gt;
|przebieg czasowy szumu&lt;br /&gt;
|przebieg czasowy szumu&lt;br /&gt;
|-&lt;br /&gt;
|Przebieg czasowy odwrotnej tr. Fouriera iloczynu widma szumu i okna prostokątnego&lt;br /&gt;
|Przebieg czasowy odwrotnej tr. Fouriera iloczynu widma szumu i okna Gaussowskiego&lt;br /&gt;
|}&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  irfft,rfft,fftshift&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
szum = np.random.randn(128*2-2)&lt;br /&gt;
SZum = rfft(szum)&lt;br /&gt;
&lt;br /&gt;
S_prost= np.zeros(128)&lt;br /&gt;
S_prost[20:30]=1&lt;br /&gt;
s_prost = fftshift(irfft(S_prost))&lt;br /&gt;
&lt;br /&gt;
t = np.arange(len(s_prost))&lt;br /&gt;
F = np.arange(len(S_prost))&lt;br /&gt;
S_gauss = np.exp(-((F-25.0)/5)**2)&lt;br /&gt;
s_gauss = fftshift(irfft(S_gauss))&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,1)&lt;br /&gt;
py.stem(F,S_prost)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,3)&lt;br /&gt;
py.plot(t,s_prost)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,5)&lt;br /&gt;
py.plot(t,szum)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,7)&lt;br /&gt;
filtrowanySygnal = fftshift(irfft(SZum*S_prost))&lt;br /&gt;
py.plot(filtrowanySygnal)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,2)&lt;br /&gt;
py.stem(F,S_gauss)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,4)&lt;br /&gt;
py.plot(t,s_gauss)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,6)&lt;br /&gt;
py.plot(t,szum)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,8)&lt;br /&gt;
filtrowanySignal = fftshift(irfft(SZum*S_gauss))&lt;br /&gt;
py.plot(filtrowanySignal)&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_3&amp;diff=4149</id>
		<title>Ćwiczenia 3</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_3&amp;diff=4149"/>
		<updated>2015-09-30T12:52:55Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Okienkować możemy też w częstości */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Twierdzenie o splocie ==&lt;br /&gt;
Na pierwszych ćwiczeniach poznaliśmy poznaliśmy operację [[Systemy_liniowe_niezmiennicze_w_czasie#Splot|splotu]] jako efekt działania systemu liniowego niezmienniczego w czasie. Poznaliśmy wówczas jego [[Systemy_liniowe_niezmiennicze_w_czasie#W.C5.82asno.C5.9Bci_splotu|własności]].&lt;br /&gt;
Okazuje się, że gdy rozważamy sprzężone ze sobą za pomocą transformaty Fouriera dziedziny czasu i częstości splot ma wiele wspólnego z mnożeniem. Związek ten można zapisać jako &lt;br /&gt;
[[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|Twierdzenie o splocie:]] &lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid2&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
g(t)=\left(s * h\right)(t)\quad \Rightarrow \quad G(f)=S(f)\cdot H(f)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
To twierdzenie działa też w drugą stronę:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
G(f)=\left(S * H\right)(f)\quad \Rightarrow \quad g(t)=s(t)\cdot h(t)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W praktyce oznacza to tyle, że jeśli w jednej dziedzinie jakieś dwa sygnały przez siebie przemnożymy, to w drugiej dziedzinie transformaty tych sygnałów splatają się. Własność ta ma bardzo ważne konsekwencje, np. przy estymacji widma skończonego fragmentu sygnału. Dlaczego?&lt;br /&gt;
&lt;br /&gt;
Wyobraźmy sobie, że mamy nieskończenie długi sygnał. Oprócz niego mamy też funkcję, która jest niezerowa tylko na skończonym odcinku. Funkcję taką będziemy nazywać oknem. Pobranie fragmentu sygnału można wyobrazić sobie jako efekt pomnożenia badanego sygnału przez okno. Ta operacja mnożenia w dziedzinie czasu, w dziedzinie częstości odpowiada splotowi widma sygnału z widmem okna. Aby uzyskać sygnał o skończonej długości odrzucamy wyzerowane odcinki. FFT widzi taki skończony odcinek jako  [[%C4%86wiczenia_2#Przed.C5.82u.C5.BCenie_przez_periodyczn.C4.85_replikacj.C4.99|periodyczne przedłużenie]].  Widać, że w praktyce estymowania widma zawsze mamy  do czynienia z widmami będącymi splotem widma sygnału i widma okna, ponieważ zawsze pracujemy z sygnałami o skończonej długości.&lt;br /&gt;
&lt;br /&gt;
===Zastosowania===&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	zamiana splotu na mnożenie&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	daje wgląd w okienkowanie&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	łatwo zrozumieć działanie filtrów&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Okienka==&lt;br /&gt;
===Wstęp===&lt;br /&gt;
* Jakie są dostępne okna w Numpy? Proszę odwiedzić stronę z [http://docs.scipy.org/doc/numpy/reference/routines.window.html dokumentacją].&lt;br /&gt;
* Jak wyglądają te okienka?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
w = np.bartlett(10)&lt;br /&gt;
print w&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Badanie własności okien===&lt;br /&gt;
&lt;br /&gt;
* Wykreśl okienko Bartletta o długości 100 i 101 próbek.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as py&lt;br /&gt;
&lt;br /&gt;
window = np.bartlett(101)&lt;br /&gt;
py.plot(window)&lt;br /&gt;
py.title(&amp;quot;okno Bartletta&amp;quot;)&lt;br /&gt;
py.ylabel(&amp;quot;Amplituda&amp;quot;)&lt;br /&gt;
py.xlabel(u&amp;quot;próbki&amp;quot;)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Proszę wykreślić widmo amplitudowe okna Bartletta o długości 101 próbek w skali [[wikipl:Decybel|dB]] (&amp;lt;tt&amp;gt;20*np.log10(.)&amp;lt;/tt&amp;gt;), raz korzystając z fft o naturalnej długości okna &amp;lt;tt&amp;gt;W = fft(okno)&amp;lt;/tt&amp;gt;, a drugi raz korzystając z przedłużenia zerami (w tym przypadku dostaniemy interpolowaną wersję widma) &amp;lt;tt&amp;gt;W = fft(okno, 2048)&amp;lt;/tt&amp;gt;. Proszę zwrócić uwagę na charakterystyczne elementy: szerokość piku głównego, szybkość zanikania listków bocznych, zera. &lt;br /&gt;
&lt;br /&gt;
Przydatna może być tu funkcja do obliczania widma (proszę przeanalizować kod i w razie wątpliwości poprosić o objaśnienie):&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1.0/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 *&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import fft, fftshift&lt;br /&gt;
import matplotlib.pyplot as py&lt;br /&gt;
&lt;br /&gt;
window = np.bartlett(51)&lt;br /&gt;
&lt;br /&gt;
W = fft(window)/len(window)&lt;br /&gt;
# rysować będziemy w skali logarytmicznej&lt;br /&gt;
widmo = abs(fftshift(W))&lt;br /&gt;
widmo_dB = 20*np.log10(widmo)&lt;br /&gt;
f = np.linspace(-0.5,0.5,len(W))&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(f,widmo_dB)&lt;br /&gt;
py.axis('tight')&lt;br /&gt;
&lt;br /&gt;
W_zeropadded = fft(window, 2048) / len(window)&lt;br /&gt;
widmo_zeropadded = abs(fftshift(W_zeropadded))&lt;br /&gt;
f = np.linspace(-0.5,0.5,len(W_zeropadded))&lt;br /&gt;
widmo_dB_zeropadded = 20*np.log10(widmo_zeropadded)&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(f ,widmo_dB_zeropadded)&lt;br /&gt;
py.title(&amp;quot;widmo okna Bartletta&amp;quot;)&lt;br /&gt;
py.ylabel(u&amp;quot;Wartość [dB]&amp;quot;)&lt;br /&gt;
py.xlabel(u&amp;quot;znormalizowana częstość&amp;quot;)&lt;br /&gt;
py.axis('tight')&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* A jakie własności ma okno prostokątne? Najprościej można je zrobić tak: &amp;lt;tt&amp;gt;window = np.ones(N)&amp;lt;/tt&amp;gt;. Proszę wykonać analogiczne rysunki jak dla okna Bartletta.&lt;br /&gt;
&lt;br /&gt;
* Proszę porównać przebiegi czasowe i własności widmowe pozostałych okien dostępnych w numpy, tzn.: &lt;br /&gt;
**blackman(M) 	&lt;br /&gt;
**hamming(M) 	&lt;br /&gt;
**hanning(M) 	&lt;br /&gt;
**kaiser(M, beta)&lt;br /&gt;
&lt;br /&gt;
===Własności okien w działaniu===&lt;br /&gt;
==== Okienko i szerokość prążka w widmie ====&lt;br /&gt;
* Wygeneruj sinusoidę o częstości &amp;lt;math&amp;gt;f=10.2&amp;lt;/math&amp;gt; Hz fazie 0, czasie trwania &amp;lt;math&amp;gt;T=1&amp;lt;/math&amp;gt; s, i częstości próbkowania &amp;lt;math&amp;gt;Fs=100&amp;lt;/math&amp;gt; Hz&lt;br /&gt;
* Wygeneruj okno prostokątne o długości równej długości sinusoidy.&lt;br /&gt;
* Zokienkuj sygnał mnożąc sinusoidę przez okienko&lt;br /&gt;
* Wykreśl zokienkowany sygnał, widmo zokienkowanego sygnału, widmo okienka&lt;br /&gt;
* Powtórz powyższe kroki dla okienek Bartletta, Hanna, Hamminga i Blackmana. Przy wykreślaniu widma zokienkowanego sygnału ustal zakres osi pionowej na [-50 10] (zastosuj &amp;lt;tt&amp;gt;py.ylim((-50,10)&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
* Proszę porównać widma otrzymane dla poszczególnych typów okienek.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 10.2, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,1)&lt;br /&gt;
okno = np.ones(len(x))/np.sqrt(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany prostokątem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,2)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego prostokątem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,3)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo prostokąta')&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,4)&lt;br /&gt;
okno = np.blackman(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Blackmanem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,5)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Blackmanem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,6)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Blackmana')&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,7)&lt;br /&gt;
okno = np.hamming(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Hamming')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,8)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Hamming')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,9)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Hamming')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
====Wpływ okienkowania na wykrywalność składowych o różnej amplitudzie ====&lt;br /&gt;
* Wygeneruj sygnał będący sumą dwóch sinusoid o fazie 0, czasie trwania &amp;lt;math&amp;gt;T=1&amp;lt;/math&amp;gt; s, i częstości próbkowania &amp;lt;math&amp;gt;Fs=100&amp;lt;/math&amp;gt; Hz. Jedna niech ma częstość &amp;lt;math&amp;gt;f=10.2&amp;lt;/math&amp;gt; Hz. Częstość drugiej, w kolejnych zapuszczeniach skryptu proszę zmieniać od 11,4 do 16,4 Hz z krokiem co 0,5 Hz.&lt;br /&gt;
* Jaki jest wpływ okienek na możliwości rozróżnienia dwóch częstości?&lt;br /&gt;
* Proszę powtórzyć iteracje dla przypadku gdy druga z sinusoid ma 10-krotnie niższą amplitudę.&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source  lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x1,t) = sin(f = 10.2, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
&lt;br /&gt;
(x2,t) = sin(f = 11.4+0.5*1, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
x = x1 + 1*x2 #0.1*&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,1)&lt;br /&gt;
okno = np.ones(len(x))/np.sqrt(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany prostokątem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,2)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego prostokątem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,3)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo prostokąta')&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,4)&lt;br /&gt;
okno = np.blackman(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Blackmanem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,5)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Blackmanem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,6)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Blackmana')&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,7)&lt;br /&gt;
okno = np.hamming(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Hamming')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,8)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Hamming')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,9)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Hamming')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Okienkować możemy też w częstości===&lt;br /&gt;
&lt;br /&gt;
* Proszę wykreślić widmo, a następie obliczyć i wykreślić [[%C4%86wiczenia_2#Transformaty_rzeczywiste_i_Hermitowskie|odwrotną transformatę Fouriera dla sygnału rzeczywistego]] zadanego w dziedzinie częstości przez (poniższy kod definiuje sygnał w dodatniej części widma):&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
S = np.zeros(128)&lt;br /&gt;
S[21] = 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Proszę wykreślić okienko prostokątne w częstości, pozycja 1 w binach częstości od 21 do 30, a następnie wykreślić odpowiadający mu sygnał w dziedzinie czasu.&lt;br /&gt;
&lt;br /&gt;
* Koncepcyjnie najprostszym filtrem jest operacja przemnożenia widma sygnału przez okienko w dziedzinie częstości a następnie zastosowanie odwrotnej transformaty Fouriera. Co stanie się z sygnałem w dziedzinie czasu, a co w dziedzinie częstości, jeśli chcielibyśmy przefiltrować go pasmowo przy użyciu filtra pasmowo przepustowego z poprzedniego punktu?&lt;br /&gt;
 * &amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  irfft,fftshift&lt;br /&gt;
 &lt;br /&gt;
S= np.zeros(128)&lt;br /&gt;
S[21:28] = 1&lt;br /&gt;
&lt;br /&gt;
s = fftshift(irfft(S))&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
F = range(len(S))&lt;br /&gt;
py.stem(F,S)&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
t = range(len(s))&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Porównajmy działanie najprostszych filtrów fft na biały szum.&lt;br /&gt;
** Proszę wytworzyć sygnał będący białym szumem o długości 256 próbek.&lt;br /&gt;
** Policz transformatę rzeczywistą tego sygnału.&lt;br /&gt;
** Przygotuj dwa okna w dziedzinie częstości (w części dodatniej)  o długości 129: &lt;br /&gt;
*** okno prostokątne  z jedynkami w punktach 20:30&lt;br /&gt;
*** okno Gaussowskie &amp;lt;tt&amp;gt;np.exp(-((F-25.0)/5)**2)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Przemnóż widmo sygnału przez każde z okien i oblicz odwrotną transformatę Fouriera. &lt;br /&gt;
** Zilustruj wyniki rysunkiem opisanym przez poniższą tabelkę:&lt;br /&gt;
&lt;br /&gt;
{|border = 1&lt;br /&gt;
|okno prostokątne w częstości &lt;br /&gt;
| okno Gaussowskie w częstości&lt;br /&gt;
|-&lt;br /&gt;
|przebieg czasowy odwrotnej tr. Fouriera okna Prostokątnego &lt;br /&gt;
|przebieg czasowy odwrotnej tr. Fouriera okna Gaussowskiego&lt;br /&gt;
|-&lt;br /&gt;
|przebieg czasowy szumu&lt;br /&gt;
|przebieg czasowy szumu&lt;br /&gt;
|-&lt;br /&gt;
|Przebieg czasowy odwrotnej tr. Fouriera iloczynu widma szumu i okna prostokątnego&lt;br /&gt;
|Przebieg czasowy odwrotnej tr. Fouriera iloczynu widma szumu i okna Gaussowskiego&lt;br /&gt;
|}&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  irfft,rfft,fftshift&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
szum = np.random.randn(128*2-2)&lt;br /&gt;
SZum = rfft(szum)&lt;br /&gt;
&lt;br /&gt;
S_prost= np.zeros(128)&lt;br /&gt;
S_prost[20:30]=1&lt;br /&gt;
s_prost = fftshift(irfft(S_prost))&lt;br /&gt;
&lt;br /&gt;
t = np.arange(len(s_prost))&lt;br /&gt;
F = np.arange(len(S_prost))&lt;br /&gt;
S_gauss = np.exp(-((F-25.0)/5)**2)&lt;br /&gt;
s_gauss = fftshift(irfft(S_gauss))&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,1)&lt;br /&gt;
py.stem(F,S_prost)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,3)&lt;br /&gt;
py.plot(t,s_prost)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,5)&lt;br /&gt;
py.plot(t,szum)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,7)&lt;br /&gt;
filtrowanySygnal = fftshift(irfft(SZum*S_prost))&lt;br /&gt;
py.plot(filtrowanySygnal)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,2)&lt;br /&gt;
py.stem(F,S_gauss)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,4)&lt;br /&gt;
py.plot(t,s_gauss)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,6)&lt;br /&gt;
py.plot(t,szum)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,8)&lt;br /&gt;
filtrowanySignal = fftshift(irfft(SZum*S_gauss))&lt;br /&gt;
py.plot(filtrowanySignal)&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_3&amp;diff=4148</id>
		<title>Ćwiczenia 3</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_3&amp;diff=4148"/>
		<updated>2015-09-30T12:51:59Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Badanie własności okien */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Twierdzenie o splocie ==&lt;br /&gt;
Na pierwszych ćwiczeniach poznaliśmy poznaliśmy operację [[Systemy_liniowe_niezmiennicze_w_czasie#Splot|splotu]] jako efekt działania systemu liniowego niezmienniczego w czasie. Poznaliśmy wówczas jego [[Systemy_liniowe_niezmiennicze_w_czasie#W.C5.82asno.C5.9Bci_splotu|własności]].&lt;br /&gt;
Okazuje się, że gdy rozważamy sprzężone ze sobą za pomocą transformaty Fouriera dziedziny czasu i częstości splot ma wiele wspólnego z mnożeniem. Związek ten można zapisać jako &lt;br /&gt;
[[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|Twierdzenie o splocie:]] &lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid2&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
g(t)=\left(s * h\right)(t)\quad \Rightarrow \quad G(f)=S(f)\cdot H(f)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
To twierdzenie działa też w drugą stronę:&lt;br /&gt;
&amp;lt;equation id=&amp;quot;uid3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
G(f)=\left(S * H\right)(f)\quad \Rightarrow \quad g(t)=s(t)\cdot h(t)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/equation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W praktyce oznacza to tyle, że jeśli w jednej dziedzinie jakieś dwa sygnały przez siebie przemnożymy, to w drugiej dziedzinie transformaty tych sygnałów splatają się. Własność ta ma bardzo ważne konsekwencje, np. przy estymacji widma skończonego fragmentu sygnału. Dlaczego?&lt;br /&gt;
&lt;br /&gt;
Wyobraźmy sobie, że mamy nieskończenie długi sygnał. Oprócz niego mamy też funkcję, która jest niezerowa tylko na skończonym odcinku. Funkcję taką będziemy nazywać oknem. Pobranie fragmentu sygnału można wyobrazić sobie jako efekt pomnożenia badanego sygnału przez okno. Ta operacja mnożenia w dziedzinie czasu, w dziedzinie częstości odpowiada splotowi widma sygnału z widmem okna. Aby uzyskać sygnał o skończonej długości odrzucamy wyzerowane odcinki. FFT widzi taki skończony odcinek jako  [[%C4%86wiczenia_2#Przed.C5.82u.C5.BCenie_przez_periodyczn.C4.85_replikacj.C4.99|periodyczne przedłużenie]].  Widać, że w praktyce estymowania widma zawsze mamy  do czynienia z widmami będącymi splotem widma sygnału i widma okna, ponieważ zawsze pracujemy z sygnałami o skończonej długości.&lt;br /&gt;
&lt;br /&gt;
===Zastosowania===&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	zamiana splotu na mnożenie&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	daje wgląd w okienkowanie&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	łatwo zrozumieć działanie filtrów&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Okienka==&lt;br /&gt;
===Wstęp===&lt;br /&gt;
* Jakie są dostępne okna w Numpy? Proszę odwiedzić stronę z [http://docs.scipy.org/doc/numpy/reference/routines.window.html dokumentacją].&lt;br /&gt;
* Jak wyglądają te okienka?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
w = np.bartlett(10)&lt;br /&gt;
print w&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Badanie własności okien===&lt;br /&gt;
&lt;br /&gt;
* Wykreśl okienko Bartletta o długości 100 i 101 próbek.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as py&lt;br /&gt;
&lt;br /&gt;
window = np.bartlett(101)&lt;br /&gt;
py.plot(window)&lt;br /&gt;
py.title(&amp;quot;okno Bartletta&amp;quot;)&lt;br /&gt;
py.ylabel(&amp;quot;Amplituda&amp;quot;)&lt;br /&gt;
py.xlabel(u&amp;quot;próbki&amp;quot;)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Proszę wykreślić widmo amplitudowe okna Bartletta o długości 101 próbek w skali [[wikipl:Decybel|dB]] (&amp;lt;tt&amp;gt;20*np.log10(.)&amp;lt;/tt&amp;gt;), raz korzystając z fft o naturalnej długości okna &amp;lt;tt&amp;gt;W = fft(okno)&amp;lt;/tt&amp;gt;, a drugi raz korzystając z przedłużenia zerami (w tym przypadku dostaniemy interpolowaną wersję widma) &amp;lt;tt&amp;gt;W = fft(okno, 2048)&amp;lt;/tt&amp;gt;. Proszę zwrócić uwagę na charakterystyczne elementy: szerokość piku głównego, szybkość zanikania listków bocznych, zera. &lt;br /&gt;
&lt;br /&gt;
Przydatna może być tu funkcja do obliczania widma (proszę przeanalizować kod i w razie wątpliwości poprosić o objaśnienie):&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1.0/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 *&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import fft, fftshift&lt;br /&gt;
import matplotlib.pyplot as py&lt;br /&gt;
&lt;br /&gt;
window = np.bartlett(51)&lt;br /&gt;
&lt;br /&gt;
W = fft(window)/len(window)&lt;br /&gt;
# rysować będziemy w skali logarytmicznej&lt;br /&gt;
widmo = abs(fftshift(W))&lt;br /&gt;
widmo_dB = 20*np.log10(widmo)&lt;br /&gt;
f = np.linspace(-0.5,0.5,len(W))&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(f,widmo_dB)&lt;br /&gt;
py.axis('tight')&lt;br /&gt;
&lt;br /&gt;
W_zeropadded = fft(window, 2048) / len(window)&lt;br /&gt;
widmo_zeropadded = abs(fftshift(W_zeropadded))&lt;br /&gt;
f = np.linspace(-0.5,0.5,len(W_zeropadded))&lt;br /&gt;
widmo_dB_zeropadded = 20*np.log10(widmo_zeropadded)&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(f ,widmo_dB_zeropadded)&lt;br /&gt;
py.title(&amp;quot;widmo okna Bartletta&amp;quot;)&lt;br /&gt;
py.ylabel(u&amp;quot;Wartość [dB]&amp;quot;)&lt;br /&gt;
py.xlabel(u&amp;quot;znormalizowana częstość&amp;quot;)&lt;br /&gt;
py.axis('tight')&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* A jakie własności ma okno prostokątne? Najprościej można je zrobić tak: &amp;lt;tt&amp;gt;window = np.ones(N)&amp;lt;/tt&amp;gt;. Proszę wykonać analogiczne rysunki jak dla okna Bartletta.&lt;br /&gt;
&lt;br /&gt;
* Proszę porównać przebiegi czasowe i własności widmowe pozostałych okien dostępnych w numpy, tzn.: &lt;br /&gt;
**blackman(M) 	&lt;br /&gt;
**hamming(M) 	&lt;br /&gt;
**hanning(M) 	&lt;br /&gt;
**kaiser(M, beta)&lt;br /&gt;
&lt;br /&gt;
===Własności okien w działaniu===&lt;br /&gt;
==== Okienko i szerokość prążka w widmie ====&lt;br /&gt;
* Wygeneruj sinusoidę o częstości &amp;lt;math&amp;gt;f=10.2&amp;lt;/math&amp;gt; Hz fazie 0, czasie trwania &amp;lt;math&amp;gt;T=1&amp;lt;/math&amp;gt; s, i częstości próbkowania &amp;lt;math&amp;gt;Fs=100&amp;lt;/math&amp;gt; Hz&lt;br /&gt;
* Wygeneruj okno prostokątne o długości równej długości sinusoidy.&lt;br /&gt;
* Zokienkuj sygnał mnożąc sinusoidę przez okienko&lt;br /&gt;
* Wykreśl zokienkowany sygnał, widmo zokienkowanego sygnału, widmo okienka&lt;br /&gt;
* Powtórz powyższe kroki dla okienek Bartletta, Hanna, Hamminga i Blackmana. Przy wykreślaniu widma zokienkowanego sygnału ustal zakres osi pionowej na [-50 10] (zastosuj &amp;lt;tt&amp;gt;py.ylim((-50,10)&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
* Proszę porównać widma otrzymane dla poszczególnych typów okienek.&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x,t) = sin(f = 10.2, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,1)&lt;br /&gt;
okno = np.ones(len(x))/np.sqrt(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany prostokątem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,2)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego prostokątem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,3)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo prostokąta')&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,4)&lt;br /&gt;
okno = np.blackman(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Blackmanem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,5)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Blackmanem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,6)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Blackmana')&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,7)&lt;br /&gt;
okno = np.hamming(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Hamming')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,8)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Hamming')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,9)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Hamming')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
====Wpływ okienkowania na wykrywalność składowych o różnej amplitudzie ====&lt;br /&gt;
* Wygeneruj sygnał będący sumą dwóch sinusoid o fazie 0, czasie trwania &amp;lt;math&amp;gt;T=1&amp;lt;/math&amp;gt; s, i częstości próbkowania &amp;lt;math&amp;gt;Fs=100&amp;lt;/math&amp;gt; Hz. Jedna niech ma częstość &amp;lt;math&amp;gt;f=10.2&amp;lt;/math&amp;gt; Hz. Częstość drugiej, w kolejnych zapuszczeniach skryptu proszę zmieniać od 11,4 do 16,4 Hz z krokiem co 0,5 Hz.&lt;br /&gt;
* Jaki jest wpływ okienek na możliwości rozróżnienia dwóch częstości?&lt;br /&gt;
* Proszę powtórzyć iteracje dla przypadku gdy druga z sinusoid ma 10-krotnie niższą amplitudę.&lt;br /&gt;
&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source  lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  fft, fftfreq, fftshift&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
    '''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
    Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
    1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
    '''&lt;br /&gt;
 &lt;br /&gt;
    dt = 1.0/Fs&lt;br /&gt;
    t = np.arange(0,T,dt)&lt;br /&gt;
    s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
    return (s,t)&lt;br /&gt;
def widmo_dB(s, N_fft , F_samp):&lt;br /&gt;
    S = fft(s,N_fft)/np.sqrt(N_fft)&lt;br /&gt;
    S_dB = 20*np.log10(np.abs(S))&lt;br /&gt;
    F = fftfreq(N_fft, 1/F_samp)&lt;br /&gt;
    return (fftshift(S_dB),fftshift(F))&lt;br /&gt;
&lt;br /&gt;
F_samp = 100.0&lt;br /&gt;
(x1,t) = sin(f = 10.2, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
&lt;br /&gt;
(x2,t) = sin(f = 11.4+0.5*1, T =1.0, Fs = F_samp, phi = 0)&lt;br /&gt;
x = x1 + 1*x2 #0.1*&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,1)&lt;br /&gt;
okno = np.ones(len(x))/np.sqrt(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany prostokątem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,2)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego prostokątem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,3)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo prostokąta')&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,4)&lt;br /&gt;
okno = np.blackman(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Blackmanem')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,5)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Blackmanem')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,6)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Blackmana')&lt;br /&gt;
#&lt;br /&gt;
py.subplot(3,3,7)&lt;br /&gt;
okno = np.hamming(len(x))&lt;br /&gt;
s = x*okno&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.title(u' sygnał okienkowany Hamming')&lt;br /&gt;
# &lt;br /&gt;
py.subplot(3,3,8)&lt;br /&gt;
(S,F) = widmo_dB(s,len(s),F_samp) &lt;br /&gt;
py.plot(F,S)&lt;br /&gt;
py.title(u'widmo sygnału okienkowanego Hamming')&lt;br /&gt;
py.ylim((-50,10))&lt;br /&gt;
&lt;br /&gt;
#widmo okna&lt;br /&gt;
&lt;br /&gt;
(Okno, F) = widmo_dB(okno,1024,F_samp)&lt;br /&gt;
py.subplot(3,3,9)&lt;br /&gt;
py.plot(F,Okno)&lt;br /&gt;
py.title('widmo Hamming')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Okienkować możemy też w częstości===&lt;br /&gt;
&lt;br /&gt;
* Proszę wykreślić widmo, a następie obliczyć i wykreślić [[%C4%86wiczenia_2#Transformaty_rzeczywiste_i_Hermitowskie|odwrotną transformatę Fouriera dla sygnału rzeczywistego]] zadanego w dziedzinie częstości przez (poniższy kod definiuje sygnał w dodatniej części widma):&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
S= np.zeros(128)&lt;br /&gt;
S[21]=1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Proszę wykreślić okienko prostokątne w częstości, pozycja 1 w binach częstości od 21 do 30, a następnie wykreślić odpowiadający mu sygnał w dziedzinie czasu.&lt;br /&gt;
&lt;br /&gt;
* Koncepcyjnie najprostszym filtrem jest operacja przemnożenia widma sygnału przez okienko w dziedzinie częstości a następnie zastosowanie odwrotnej transformaty Fouriera. Co stanie się z sygnałem w dziedzinie czasu, a co w dziedzinie częstości, jeśli chcielibyśmy przefiltrować go pasmowo przy użyciu filtra pasmowo przepustowego z poprzedniego punktu?&lt;br /&gt;
 * &amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  irfft,fftshift&lt;br /&gt;
 &lt;br /&gt;
S= np.zeros(128)&lt;br /&gt;
S[21:28]=1&lt;br /&gt;
&lt;br /&gt;
s = fftshift(irfft(S))&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
F = range(len(S))&lt;br /&gt;
py.stem(F,S)&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
t = range(len(s))&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Porównajmy działanie najprostszych filtrów fft na biały szum.&lt;br /&gt;
** Proszę wytworzyć sygnał będący białym szumem o długości 256 próbek.&lt;br /&gt;
** Policz transformatę rzeczywistą tego sygnału.&lt;br /&gt;
** Przygotuj dwa okna w dziedzinie częstości (w części dodatniej)  o długości 129: &lt;br /&gt;
*** okno prostokątne  z jedynkami w punktach 20:30&lt;br /&gt;
*** okno Gaussowskie &amp;lt;tt&amp;gt;np.exp(-((F-25.0)/5)**2)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Przemnóż widmo sygnału przez każde z okien i oblicz odwrotną transformatę Fouriera. &lt;br /&gt;
** Zilustruj wyniki rysunkiem opisanym przez poniższą tabelkę:&lt;br /&gt;
{|border = 1&lt;br /&gt;
|okno prostokątne w częstości &lt;br /&gt;
| okno Gaussowskie w częstości&lt;br /&gt;
|-&lt;br /&gt;
|przebieg czasowy odwrotnej tr. Fouriera okna Prostokątnego &lt;br /&gt;
|przebieg czasowy odwrotnej tr. Fouriera okna Gaussowskiego&lt;br /&gt;
|-&lt;br /&gt;
|przebieg czasowy szumu&lt;br /&gt;
|przebieg czasowy szumu&lt;br /&gt;
|-&lt;br /&gt;
|Przebieg czasowy odwrotnej tr. Fouriera iloczynu widma szumu i okna prostokątnego&lt;br /&gt;
|Przebieg czasowy odwrotnej tr. Fouriera iloczynu widma szumu i okna Gaussowskiego&lt;br /&gt;
|}&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
from numpy.fft import  irfft,rfft,fftshift&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
szum = np.random.randn(128*2-2)&lt;br /&gt;
SZum = rfft(szum)&lt;br /&gt;
&lt;br /&gt;
S_prost= np.zeros(128)&lt;br /&gt;
S_prost[20:30]=1&lt;br /&gt;
s_prost = fftshift(irfft(S_prost))&lt;br /&gt;
&lt;br /&gt;
t = np.arange(len(s_prost))&lt;br /&gt;
F = np.arange(len(S_prost))&lt;br /&gt;
S_gauss = np.exp(-((F-25.0)/5)**2)&lt;br /&gt;
s_gauss = fftshift(irfft(S_gauss))&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,1)&lt;br /&gt;
py.stem(F,S_prost)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,3)&lt;br /&gt;
py.plot(t,s_prost)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,5)&lt;br /&gt;
py.plot(t,szum)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,7)&lt;br /&gt;
filtrowanySygnal = fftshift(irfft(SZum*S_prost))&lt;br /&gt;
py.plot(filtrowanySygnal)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,2)&lt;br /&gt;
py.stem(F,S_gauss)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,4)&lt;br /&gt;
py.plot(t,s_gauss)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,6)&lt;br /&gt;
py.plot(t,szum)&lt;br /&gt;
&lt;br /&gt;
py.subplot(4,2,8)&lt;br /&gt;
filtrowanySignal = fftshift(irfft(SZum*S_gauss))&lt;br /&gt;
py.plot(filtrowanySignal)&lt;br /&gt;
&lt;br /&gt;
py.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4147</id>
		<title>Ćwiczenia 2 2</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4147"/>
		<updated>2015-09-30T12:50:21Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Długość sygnału a rozdzielczość widma FFT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Zadania ===&lt;br /&gt;
&lt;br /&gt;
==== Współczynniki obliczane przez FFT ====&lt;br /&gt;
Najprostsza sytuacja: Badamy współczynniki zwracane przez &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt; dla sinusoid o różnych częstościach. Wykorzystujemy funkcje do generacji sygnałów napisane na poprzednich zajęciach.&lt;br /&gt;
&lt;br /&gt;
* Proszę kolejno wygenerować sinusoidy o długości 1s próbkowaną 128Hz i częstościach 1,10,30, 64  i  0 Hz. Dla tych sinusoid proszę policzyć transformaty Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wyglądają otrzymane wykresy?&lt;br /&gt;
** Czy coś szczególnego dzieje się dla częstości 0 i 64Hz? Czy w tych skrajnych przypadkach faza sygnału ma wpływ na wynik transformaty? &lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał delta położony w sekundzie 0,5 na odcinku czasu o długości 1s próbkowany 128Hz. Dla takiego sygnału proszę policzyć transformatę Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wygląda transformata funkcji delta? Jakie częstości w sobie zawiera?&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
# skrypt implemetujący polecenia w sekcji&lt;br /&gt;
# Współczynniki obliczane przez FFT&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
def delta(t0=0.5, T=1  ,Fs = 128):&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	d = np.zeros(len(t))&lt;br /&gt;
	d[np.ceil(t0*Fs)]=1&lt;br /&gt;
	return (d,t)&lt;br /&gt;
 &lt;br /&gt;
# do pytania 1&lt;br /&gt;
(s,t) = sin(f=2,T=1,Fs=10,phi=np.pi/2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
print S&lt;br /&gt;
# na wydruku należy zauważyć, że wsółczynniki są zespolone i parami sprzężone&lt;br /&gt;
&lt;br /&gt;
# do pytania 2&lt;br /&gt;
(s,t) = sin(f=1,T=1,Fs=128,phi=np.pi/3) # f=0,10,30,64&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&lt;br /&gt;
# do pytania 3&lt;br /&gt;
(s,t) = delta(t0=0.5, T=1  ,Fs = 128)&lt;br /&gt;
&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(2)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Rekonstrukcja sygnału ze współczynników =====&lt;br /&gt;
Reprezentacja sygnałów w dziedzinie częstości jest dualna do reprezentacji  w dziedzinie czasu. To znaczy, że jedną reprezentację można przekształcić w drugą. Do przejścia z dziedziny czasu do częstości używaliśmy transformaty Fouriera (zaimplemantowanej w &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt;). Przejścia z dziedziny częstości do czasu dokonujemy przy pomocy odwrotnej transformaty Fouriera (zaimplementowanej jako &amp;lt;tt&amp;gt;ifft&amp;lt;/tt&amp;gt;. Mając (zespolone) współczynniki w dziedzinie częstości dla pewnego sygnału,możemy odzyskać jego przebieg czasowy.&lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał &amp;lt;math&amp;gt;s(t) = \sin(2\pi t \cdot 1)+\sin\left(2 \pi  t \cdot 3+\frac{\pi}{5}\right) &amp;lt;/math&amp;gt; o długości 2,5s próbkowany 10Hz, obliczyć jego transformatę Fouriera, a następnie zrekonstruować przebieg czasowy. Sygnał oryginalny i zrekonstruowany wykreślić na jednym rysunku.  Korzystając z naszych funkcji generację sygnału można zapisać tak:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
(s1,t) = sin(f=1, T=2.5, Fs=10, phi=0)&lt;br /&gt;
(s2,t) = sin(f=3, T=2.5, Fs=10, phi=np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Dla porównania proszę zrekonstruować sygnał korzystając jawnie z postaci odwrotnej transformaty Fouriera danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;x(n)=\frac{1}{N} \sum_{k=0}^{N-1} S[k] \cdot \exp\left(2j \pi n\frac{ k}{N}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
:Zwróćmy uwagę, że ''n'' w powyższym wzorze to indeksy punktów czasu, zatem wiążą się one z czasem zwracanym przez nasze funkcje następująco:&lt;br /&gt;
:&amp;lt;tt&amp;gt;n=np.arange(0,len(t),1)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
zatem kod rekonstruujący może być np. taki:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
n=np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
&lt;br /&gt;
def f1(dt):&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co dt	'''&lt;br /&gt;
	t = np.arange(0,2,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*t)+np.sin(2*np.pi*3*t+np.pi/5)#np.abs(t)#&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
dt = 0.1	&lt;br /&gt;
Fs = 1.0/dt&lt;br /&gt;
&lt;br /&gt;
(s1,t) = sin(f=1,T=2.5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2,t) = sin(f=3,T=2.5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
S = FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
N = len(t)&lt;br /&gt;
&lt;br /&gt;
s_ifft = FFT.ifft(S)&lt;br /&gt;
&lt;br /&gt;
n = np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.plot(t,s_ifft,'bo',markersize = 3 )&lt;br /&gt;
py.plot(t,(s_rekonstrukcja),'gx',markersize = 8)&lt;br /&gt;
py.plot(t,s,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Rekonstrukcja na dłuższym odcinku czasu:=====&lt;br /&gt;
Korzystając z wyników poprzedniego polecenia proszę porównać wykres funkcji zadanych wzorami dla odcinak czasu o długości 5s i rekonstrukcję sygnału o długości 5s otrzymanego ze współczynników Fouriera obliczonych dla 2,5s  odcinak czasu.&lt;br /&gt;
* Na jakim odcinku czasu sygnały są zgodne?&lt;br /&gt;
* Co dzieje się na dalszym odcinku czasu?&lt;br /&gt;
 *&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
dalszy ciąg poprzedniego kodu:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.figure(2)&lt;br /&gt;
(s1_d,t_d) = sin(f=1,T=5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2_d,t_d) = sin(f=3,T=5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s_d = s1_d + s2_d&lt;br /&gt;
&lt;br /&gt;
# rekonstrukcja bazująca na współczynnikach otzrzynmanych dla 2sek fragmentu sygnału&lt;br /&gt;
n=np.arange(0,len(t_d),1)&lt;br /&gt;
s_rekonstrukcja_dluga = np.zeros(len(t_d)) &lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja_dluga += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
py.plot(t_d,(s_rekonstrukcja_dluga),'gx-',markersize = 8)&lt;br /&gt;
py.plot(t_d,s_d,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Przykład:=====&lt;br /&gt;
Oblicz współczynniki numerycznie korzystając z &amp;lt;tt&amp;gt;numpy.fft.fft&amp;lt;/tt&amp;gt;, porównaj z otrzymanymi analitycznie. Zrób wykresy funkcji i wartości bezwzględnej transformaty. Dla funkcji ''f'' z poprzedniego przykładu danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt; f(t)=|t| &amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-1, 1]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1,&lt;br /&gt;
&lt;br /&gt;
Obliczamy współczynniki i robimy wykres:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def f1():&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co 0.1	'''&lt;br /&gt;
	dt = 0.1	&lt;br /&gt;
	t = np.arange(-1,1,dt)&lt;br /&gt;
	s = np.abs(t)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
Fs = 10.0&lt;br /&gt;
(s,t) = f1() #generuję sygnał&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.stem(t,s)&lt;br /&gt;
&lt;br /&gt;
S=FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
F = FFT.fftfreq(len(S),Fs) # obliczam skalę częstości &lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.stem(F,np.abs(S)/len(s)) # wykreślam widmo amplitudowe&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Porównujemy wyniki z wynikami analitycznymi:&lt;br /&gt;
* &amp;lt;math&amp;gt; f(t) = |cos(t)|&amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-\pi, \pi]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
==== Efekt nieciągłości funkcji ====&lt;br /&gt;
* Wygenerować sinusoidę o następujących własnościach: f=10 Hz, T=1, Fs=100 Hz, i fazie = 1;&lt;br /&gt;
* Przy pomocy subplotów proszę sporządzić rysunek zgodnie z ponższym opisem:&lt;br /&gt;
** subplot(2,2,1): przebieg sygnału w czasie &lt;br /&gt;
** subplot(2,2,2): moduł jego transformaty Fouriera (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(len(s), 1/Fs)&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; to nasz sygnał),&lt;br /&gt;
** subplot(2,2,3): Proszę wykreślić trzykrotnie periodycznie powielony oryginalny sygnał. Można go skonstruować wywołując funkcję: &amp;lt;tt&amp;gt;s_period = np.concatenate((s,s,s))&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** subplot(2,2,4): moduł transformaty Fouriera &amp;lt;tt&amp;gt;s_period&amp;lt;/tt&amp;gt; (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(3*len(s), 1/Fs)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Powtórz te same kroki dla sinusa o częstości 10.3 Hz.&lt;br /&gt;
Pytania:&lt;br /&gt;
# Czym różnią się przedłużenia sinusoidy 10 Hz od sinusoidy 10.3 Hz? Proszę zwrócić uwagę na miejsca sklejania sygnałów. &amp;lt;!--Porównaj z wynikami otrzymanymi w zagadnieniu '''Rekonstrukcja na dłuższym odcinku czasu'''.--&amp;gt;&lt;br /&gt;
# Skąd bierze się widoczna różnica w widmie sinusoidy 10 Hz i 10.3 Hz? &lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s,t) = sin(f = 10.3, T =1, Fs = 100, phi = 1)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s))&lt;br /&gt;
t_period = np.arange(0,3,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Długość sygnału a rozdzielczość widma FFT ====&lt;br /&gt;
Z dotychczasowych rozważań o transformacie Fouriera ograniczonych w czasie sygnałów dyskretnych wynika, że w widmie reprezentowane są częstości od &amp;lt;math&amp;gt;-F_N&amp;lt;/math&amp;gt; do &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; to częstości Nyquista. Dostępnych binów częstości jest ''N'' - tyle samo ile obserwowanych punktów sygnału. Zatem zwiększenie długości sygnału w czasie poprawia &amp;quot;rozdzielczość&amp;quot;  reprezentacji częstotliwościowej sygnału. &lt;br /&gt;
&lt;br /&gt;
Załóżmy, że dysponujemy jedynie sekwencją ''N'' próbek pewnego sygnału. Rozważymy teraz jakie można przyjąć strategie przedłużania tego sygnału w celu zwiększenia gęstości binów częstotliwościowych i jakie te strategie mają konsekwencje.&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Przedłużenie przez periodyczną replikację =====&lt;br /&gt;
Rozważając poprzednie przykłady zauważyliśmy, że FFT &amp;quot;widzi&amp;quot; sygnał tak jakby to była nieskończona periodyczna replikacja fragmentu sygnału podanego na wejście. Zatem najbardziej naturalną formą przedłużenia sygnału może wydawać się postępowanie zgodnie z tym sposobem widzenia i dołożenie do sygnału kolejnych segmentów zawierających kopie analizowanego fragmentu sygnału. Zbadajmy empirycznie efekty takiego podejścia. &lt;br /&gt;
&lt;br /&gt;
* Proszę wytworzyć i wykreślić sinusoidy o częstościach 15 i 20 Hz, trwające 0.1s i próbkowane 100Hz. &lt;br /&gt;
** Ile próbek sygnału dostajemy?&lt;br /&gt;
** Proszę obliczyć transformatę Fouriera. Ile punktów w widmie amplitudowym otrzymujemy? Dla jakich cżęstości mamy biny?&lt;br /&gt;
** Proszę skonstruować sygnał będący złożeniem 10 kopii oryginalnego sygnału. &lt;br /&gt;
Jest to 10-krotnie dłuższy fragment sygnału, którego wersję nieskończoną opisują współczynniki obliczone przez transformatę Fouriera. Transformata policzona z takiego wydłużonego odcinak ma 10-krotnie więcej binów. W szczególności zawiera on bin 15Hz. Proszę porównać wykresy widma amplitudowego otrzymanego dla wersji krótkiej i przedłużonej sygnału. Czy wynik jest zaskakujący? Jak go można zrozumieć?&lt;br /&gt;
 * Sygnał przedłużony periodycznie nie zawiera żadnej dodatkowej informacji względem pojedynczego okresu!&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s,s,s,s,s,s,s,s))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Przedłużanie sygnału zerami =====&lt;br /&gt;
Inną popularną metodą na zwiększanie ilości binów w transformacie Fouriera jest przedłużanie sygnału zerami (zero-padding). Jest to szczególny przypadek następującego podejścia: Nasz &amp;quot;prawdziwy&amp;quot; sygnał jest długi. Oglądamy go przez prostokątne okno, które ma wartość 1 na odcinku czasu dla którego próbki mamy dostępne i 0 dla pozostałego czasu (więcej o różnych oknach będzie na kolejnych zajęciach). W efekcie możemy myśleć, że oglądany przez nas sygnał to efekt przemnożenia &amp;quot;prawdziwego&amp;quot; sygnału przez okno. Efekty takiego przedłużania proszę zbadać przy użyciu poniższego kodu. &lt;br /&gt;
* Jak można zinterpretować wyniki tego eksperymentu w świetle [[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|twierdzenia o splocie]]?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,z,z,z,z,z,z,z,z,z))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S))&lt;br /&gt;
py.stem(F,np.abs(S)/len(S),linefmt='r-', markerfmt='ro')&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4146</id>
		<title>Ćwiczenia 2 2</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4146"/>
		<updated>2015-09-30T12:32:46Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Efekt nieciągłości funkcji */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Zadania ===&lt;br /&gt;
&lt;br /&gt;
==== Współczynniki obliczane przez FFT ====&lt;br /&gt;
Najprostsza sytuacja: Badamy współczynniki zwracane przez &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt; dla sinusoid o różnych częstościach. Wykorzystujemy funkcje do generacji sygnałów napisane na poprzednich zajęciach.&lt;br /&gt;
&lt;br /&gt;
* Proszę kolejno wygenerować sinusoidy o długości 1s próbkowaną 128Hz i częstościach 1,10,30, 64  i  0 Hz. Dla tych sinusoid proszę policzyć transformaty Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wyglądają otrzymane wykresy?&lt;br /&gt;
** Czy coś szczególnego dzieje się dla częstości 0 i 64Hz? Czy w tych skrajnych przypadkach faza sygnału ma wpływ na wynik transformaty? &lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał delta położony w sekundzie 0,5 na odcinku czasu o długości 1s próbkowany 128Hz. Dla takiego sygnału proszę policzyć transformatę Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wygląda transformata funkcji delta? Jakie częstości w sobie zawiera?&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
# skrypt implemetujący polecenia w sekcji&lt;br /&gt;
# Współczynniki obliczane przez FFT&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
def delta(t0=0.5, T=1  ,Fs = 128):&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	d = np.zeros(len(t))&lt;br /&gt;
	d[np.ceil(t0*Fs)]=1&lt;br /&gt;
	return (d,t)&lt;br /&gt;
 &lt;br /&gt;
# do pytania 1&lt;br /&gt;
(s,t) = sin(f=2,T=1,Fs=10,phi=np.pi/2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
print S&lt;br /&gt;
# na wydruku należy zauważyć, że wsółczynniki są zespolone i parami sprzężone&lt;br /&gt;
&lt;br /&gt;
# do pytania 2&lt;br /&gt;
(s,t) = sin(f=1,T=1,Fs=128,phi=np.pi/3) # f=0,10,30,64&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&lt;br /&gt;
# do pytania 3&lt;br /&gt;
(s,t) = delta(t0=0.5, T=1  ,Fs = 128)&lt;br /&gt;
&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(2)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Rekonstrukcja sygnału ze współczynników =====&lt;br /&gt;
Reprezentacja sygnałów w dziedzinie częstości jest dualna do reprezentacji  w dziedzinie czasu. To znaczy, że jedną reprezentację można przekształcić w drugą. Do przejścia z dziedziny czasu do częstości używaliśmy transformaty Fouriera (zaimplemantowanej w &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt;). Przejścia z dziedziny częstości do czasu dokonujemy przy pomocy odwrotnej transformaty Fouriera (zaimplementowanej jako &amp;lt;tt&amp;gt;ifft&amp;lt;/tt&amp;gt;. Mając (zespolone) współczynniki w dziedzinie częstości dla pewnego sygnału,możemy odzyskać jego przebieg czasowy.&lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał &amp;lt;math&amp;gt;s(t) = \sin(2\pi t \cdot 1)+\sin\left(2 \pi  t \cdot 3+\frac{\pi}{5}\right) &amp;lt;/math&amp;gt; o długości 2,5s próbkowany 10Hz, obliczyć jego transformatę Fouriera, a następnie zrekonstruować przebieg czasowy. Sygnał oryginalny i zrekonstruowany wykreślić na jednym rysunku.  Korzystając z naszych funkcji generację sygnału można zapisać tak:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
(s1,t) = sin(f=1, T=2.5, Fs=10, phi=0)&lt;br /&gt;
(s2,t) = sin(f=3, T=2.5, Fs=10, phi=np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Dla porównania proszę zrekonstruować sygnał korzystając jawnie z postaci odwrotnej transformaty Fouriera danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;x(n)=\frac{1}{N} \sum_{k=0}^{N-1} S[k] \cdot \exp\left(2j \pi n\frac{ k}{N}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
:Zwróćmy uwagę, że ''n'' w powyższym wzorze to indeksy punktów czasu, zatem wiążą się one z czasem zwracanym przez nasze funkcje następująco:&lt;br /&gt;
:&amp;lt;tt&amp;gt;n=np.arange(0,len(t),1)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
zatem kod rekonstruujący może być np. taki:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
n=np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
&lt;br /&gt;
def f1(dt):&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co dt	'''&lt;br /&gt;
	t = np.arange(0,2,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*t)+np.sin(2*np.pi*3*t+np.pi/5)#np.abs(t)#&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
dt = 0.1	&lt;br /&gt;
Fs = 1.0/dt&lt;br /&gt;
&lt;br /&gt;
(s1,t) = sin(f=1,T=2.5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2,t) = sin(f=3,T=2.5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
S = FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
N = len(t)&lt;br /&gt;
&lt;br /&gt;
s_ifft = FFT.ifft(S)&lt;br /&gt;
&lt;br /&gt;
n = np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.plot(t,s_ifft,'bo',markersize = 3 )&lt;br /&gt;
py.plot(t,(s_rekonstrukcja),'gx',markersize = 8)&lt;br /&gt;
py.plot(t,s,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Rekonstrukcja na dłuższym odcinku czasu:=====&lt;br /&gt;
Korzystając z wyników poprzedniego polecenia proszę porównać wykres funkcji zadanych wzorami dla odcinak czasu o długości 5s i rekonstrukcję sygnału o długości 5s otrzymanego ze współczynników Fouriera obliczonych dla 2,5s  odcinak czasu.&lt;br /&gt;
* Na jakim odcinku czasu sygnały są zgodne?&lt;br /&gt;
* Co dzieje się na dalszym odcinku czasu?&lt;br /&gt;
 *&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
dalszy ciąg poprzedniego kodu:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.figure(2)&lt;br /&gt;
(s1_d,t_d) = sin(f=1,T=5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2_d,t_d) = sin(f=3,T=5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s_d = s1_d + s2_d&lt;br /&gt;
&lt;br /&gt;
# rekonstrukcja bazująca na współczynnikach otzrzynmanych dla 2sek fragmentu sygnału&lt;br /&gt;
n=np.arange(0,len(t_d),1)&lt;br /&gt;
s_rekonstrukcja_dluga = np.zeros(len(t_d)) &lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja_dluga += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
py.plot(t_d,(s_rekonstrukcja_dluga),'gx-',markersize = 8)&lt;br /&gt;
py.plot(t_d,s_d,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Przykład:=====&lt;br /&gt;
Oblicz współczynniki numerycznie korzystając z &amp;lt;tt&amp;gt;numpy.fft.fft&amp;lt;/tt&amp;gt;, porównaj z otrzymanymi analitycznie. Zrób wykresy funkcji i wartości bezwzględnej transformaty. Dla funkcji ''f'' z poprzedniego przykładu danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt; f(t)=|t| &amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-1, 1]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1,&lt;br /&gt;
&lt;br /&gt;
Obliczamy współczynniki i robimy wykres:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def f1():&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co 0.1	'''&lt;br /&gt;
	dt = 0.1	&lt;br /&gt;
	t = np.arange(-1,1,dt)&lt;br /&gt;
	s = np.abs(t)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
Fs = 10.0&lt;br /&gt;
(s,t) = f1() #generuję sygnał&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.stem(t,s)&lt;br /&gt;
&lt;br /&gt;
S=FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
F = FFT.fftfreq(len(S),Fs) # obliczam skalę częstości &lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.stem(F,np.abs(S)/len(s)) # wykreślam widmo amplitudowe&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Porównujemy wyniki z wynikami analitycznymi:&lt;br /&gt;
* &amp;lt;math&amp;gt; f(t) = |cos(t)|&amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-\pi, \pi]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
==== Efekt nieciągłości funkcji ====&lt;br /&gt;
* Wygenerować sinusoidę o następujących własnościach: f=10 Hz, T=1, Fs=100 Hz, i fazie = 1;&lt;br /&gt;
* Przy pomocy subplotów proszę sporządzić rysunek zgodnie z ponższym opisem:&lt;br /&gt;
** subplot(2,2,1): przebieg sygnału w czasie &lt;br /&gt;
** subplot(2,2,2): moduł jego transformaty Fouriera (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(len(s), 1/Fs)&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; to nasz sygnał),&lt;br /&gt;
** subplot(2,2,3): Proszę wykreślić trzykrotnie periodycznie powielony oryginalny sygnał. Można go skonstruować wywołując funkcję: &amp;lt;tt&amp;gt;s_period = np.concatenate((s,s,s))&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** subplot(2,2,4): moduł transformaty Fouriera &amp;lt;tt&amp;gt;s_period&amp;lt;/tt&amp;gt; (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(3*len(s), 1/Fs)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Powtórz te same kroki dla sinusa o częstości 10.3 Hz.&lt;br /&gt;
Pytania:&lt;br /&gt;
# Czym różnią się przedłużenia sinusoidy 10 Hz od sinusoidy 10.3 Hz? Proszę zwrócić uwagę na miejsca sklejania sygnałów. &amp;lt;!--Porównaj z wynikami otrzymanymi w zagadnieniu '''Rekonstrukcja na dłuższym odcinku czasu'''.--&amp;gt;&lt;br /&gt;
# Skąd bierze się widoczna różnica w widmie sinusoidy 10 Hz i 10.3 Hz? &lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s,t) = sin(f = 10.3, T =1, Fs = 100, phi = 1)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s))&lt;br /&gt;
t_period = np.arange(0,3,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Długość sygnału a rozdzielczość widma FFT ====&lt;br /&gt;
Z dotychczasowych rozważań o transformacie Fouriera ograniczonych w czasie sygnałów dyskretnych wynika, że w widmie reprezentowane są częstości od &amp;lt;math&amp;gt;-F_N&amp;lt;/math&amp;gt; do &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; to częstości Nyquista. Dostępnych binów częstości jest ''N'' - tyle samo ile obserwowanych punktów sygnału. Zatem zwiększenie długości sygnału w czasie poprawia &amp;quot;rozdzielczość&amp;quot;  reprezentacji częstotliwościowej sygnału. &lt;br /&gt;
&lt;br /&gt;
Załóżmy, że dysponujemy jedynie sekwencją ''N'' próbek pewnego sygnału. Rozważymy teraz jakie można przyjąć strategie przedłużania tego sygnału w celu zwiększenia gęstości binów częstotliwościowych i jakie te strategie mają konsekwencje.&lt;br /&gt;
&lt;br /&gt;
=====Przedłużenie przez periodyczną replikację =====&lt;br /&gt;
Rozważając poprzednie przykłady zauważyliśmy, że FFT &amp;quot;widzi&amp;quot; sygnał tak jakby to była nieskończona periodyczna replikacja fragmentu sygnału podanego na wejście. Zatem najbardziej naturalną formą przedłużenia sygnału może wydawać się postępowanie zgodnie z tym sposobem widzenia i dołożenie do sygnału kolejnych segmentów zawierających kopie analizowanego fragmentu sygnału. Zbadajmy empirycznie efekty takiego podejścia. &lt;br /&gt;
&lt;br /&gt;
* Proszę wytworzyć i wykreślić sinusoidy o częstościach 15 i 20 Hz, trwające 0.1s i próbkowane 100Hz. &lt;br /&gt;
** Ile próbek sygnału dostajemy?&lt;br /&gt;
** Proszę obliczyć transformatę Fouriera. Ile punktów w widmie amplitudowym otrzymujemy? Dla jakich cżęstości mamy biny?&lt;br /&gt;
** Proszę skonstruować sygnał będący złożeniem 10 kopii oryginalnego sygnału. &lt;br /&gt;
Jest to 10-krotnie dłuższy fragment sygnału, którego wersję nieskończoną opisują współczynniki obliczone przez transformatę Fouriera. Transformata policzona z takiego wydłużonego odcinak ma 10-krotnie więcej binów. W szczególności zawiera on bin 15Hz. Proszę porównać wykresy widma amplitudowego otrzymanego dla wersji krótkiej i przedłużonej sygnału. Czy wynik jest zaskakujący? Jak go można zrozumieć?&lt;br /&gt;
 * Sygnał przedłużony periodycznie nie zawiera żadnej dodatkowej informacji względem pojedynczego okresu!&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s,s,s,s,s,s,s,s))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Przedłużanie sygnału zerami =====&lt;br /&gt;
Inną popularną metodą na zwiększanie ilości binów w transformacie Fouriera jest przedłużanie sygnału zerami (zero-padding). Jest to szczególny przypadek następującego podejścia: Nasz &amp;quot;prawdziwy&amp;quot; sygnał jest długi. Oglądamy go przez prostokątne okno, które ma wartość 1 na odcinku czasu dla którego próbki mamy dostępne i 0 dla pozostałego czasu (więcej o różnych oknach będzie na kolejnych zajęciach). W efekcie możemy myśleć, że oglądany przez nas sygnał to efekt przemnożenia &amp;quot;prawdziwego&amp;quot; sygnału przez okno. Efekty takiego przedłużania proszę zbadać przy użyciu poniższego kodu. &lt;br /&gt;
* Jak można zinterpretować wyniki tego eksperymentu w świetle [[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|twierdzenia o splocie]]?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,z,z,z,z,z,z,z,z,z))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S))&lt;br /&gt;
py.stem(F,np.abs(S)/len(S),linefmt='r-', markerfmt='ro')&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4145</id>
		<title>Ćwiczenia 2 2</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4145"/>
		<updated>2015-09-30T12:29:13Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Efekt nieciągłości funkcji */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Zadania ===&lt;br /&gt;
&lt;br /&gt;
==== Współczynniki obliczane przez FFT ====&lt;br /&gt;
Najprostsza sytuacja: Badamy współczynniki zwracane przez &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt; dla sinusoid o różnych częstościach. Wykorzystujemy funkcje do generacji sygnałów napisane na poprzednich zajęciach.&lt;br /&gt;
&lt;br /&gt;
* Proszę kolejno wygenerować sinusoidy o długości 1s próbkowaną 128Hz i częstościach 1,10,30, 64  i  0 Hz. Dla tych sinusoid proszę policzyć transformaty Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wyglądają otrzymane wykresy?&lt;br /&gt;
** Czy coś szczególnego dzieje się dla częstości 0 i 64Hz? Czy w tych skrajnych przypadkach faza sygnału ma wpływ na wynik transformaty? &lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał delta położony w sekundzie 0,5 na odcinku czasu o długości 1s próbkowany 128Hz. Dla takiego sygnału proszę policzyć transformatę Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wygląda transformata funkcji delta? Jakie częstości w sobie zawiera?&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
# skrypt implemetujący polecenia w sekcji&lt;br /&gt;
# Współczynniki obliczane przez FFT&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
def delta(t0=0.5, T=1  ,Fs = 128):&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	d = np.zeros(len(t))&lt;br /&gt;
	d[np.ceil(t0*Fs)]=1&lt;br /&gt;
	return (d,t)&lt;br /&gt;
 &lt;br /&gt;
# do pytania 1&lt;br /&gt;
(s,t) = sin(f=2,T=1,Fs=10,phi=np.pi/2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
print S&lt;br /&gt;
# na wydruku należy zauważyć, że wsółczynniki są zespolone i parami sprzężone&lt;br /&gt;
&lt;br /&gt;
# do pytania 2&lt;br /&gt;
(s,t) = sin(f=1,T=1,Fs=128,phi=np.pi/3) # f=0,10,30,64&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&lt;br /&gt;
# do pytania 3&lt;br /&gt;
(s,t) = delta(t0=0.5, T=1  ,Fs = 128)&lt;br /&gt;
&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(2)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Rekonstrukcja sygnału ze współczynników =====&lt;br /&gt;
Reprezentacja sygnałów w dziedzinie częstości jest dualna do reprezentacji  w dziedzinie czasu. To znaczy, że jedną reprezentację można przekształcić w drugą. Do przejścia z dziedziny czasu do częstości używaliśmy transformaty Fouriera (zaimplemantowanej w &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt;). Przejścia z dziedziny częstości do czasu dokonujemy przy pomocy odwrotnej transformaty Fouriera (zaimplementowanej jako &amp;lt;tt&amp;gt;ifft&amp;lt;/tt&amp;gt;. Mając (zespolone) współczynniki w dziedzinie częstości dla pewnego sygnału,możemy odzyskać jego przebieg czasowy.&lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał &amp;lt;math&amp;gt;s(t) = \sin(2\pi t \cdot 1)+\sin\left(2 \pi  t \cdot 3+\frac{\pi}{5}\right) &amp;lt;/math&amp;gt; o długości 2,5s próbkowany 10Hz, obliczyć jego transformatę Fouriera, a następnie zrekonstruować przebieg czasowy. Sygnał oryginalny i zrekonstruowany wykreślić na jednym rysunku.  Korzystając z naszych funkcji generację sygnału można zapisać tak:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
(s1,t) = sin(f=1, T=2.5, Fs=10, phi=0)&lt;br /&gt;
(s2,t) = sin(f=3, T=2.5, Fs=10, phi=np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Dla porównania proszę zrekonstruować sygnał korzystając jawnie z postaci odwrotnej transformaty Fouriera danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;x(n)=\frac{1}{N} \sum_{k=0}^{N-1} S[k] \cdot \exp\left(2j \pi n\frac{ k}{N}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
:Zwróćmy uwagę, że ''n'' w powyższym wzorze to indeksy punktów czasu, zatem wiążą się one z czasem zwracanym przez nasze funkcje następująco:&lt;br /&gt;
:&amp;lt;tt&amp;gt;n=np.arange(0,len(t),1)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
zatem kod rekonstruujący może być np. taki:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
n=np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
&lt;br /&gt;
def f1(dt):&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co dt	'''&lt;br /&gt;
	t = np.arange(0,2,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*t)+np.sin(2*np.pi*3*t+np.pi/5)#np.abs(t)#&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
dt = 0.1	&lt;br /&gt;
Fs = 1.0/dt&lt;br /&gt;
&lt;br /&gt;
(s1,t) = sin(f=1,T=2.5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2,t) = sin(f=3,T=2.5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
S = FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
N = len(t)&lt;br /&gt;
&lt;br /&gt;
s_ifft = FFT.ifft(S)&lt;br /&gt;
&lt;br /&gt;
n = np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.plot(t,s_ifft,'bo',markersize = 3 )&lt;br /&gt;
py.plot(t,(s_rekonstrukcja),'gx',markersize = 8)&lt;br /&gt;
py.plot(t,s,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Rekonstrukcja na dłuższym odcinku czasu:=====&lt;br /&gt;
Korzystając z wyników poprzedniego polecenia proszę porównać wykres funkcji zadanych wzorami dla odcinak czasu o długości 5s i rekonstrukcję sygnału o długości 5s otrzymanego ze współczynników Fouriera obliczonych dla 2,5s  odcinak czasu.&lt;br /&gt;
* Na jakim odcinku czasu sygnały są zgodne?&lt;br /&gt;
* Co dzieje się na dalszym odcinku czasu?&lt;br /&gt;
 *&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
dalszy ciąg poprzedniego kodu:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.figure(2)&lt;br /&gt;
(s1_d,t_d) = sin(f=1,T=5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2_d,t_d) = sin(f=3,T=5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s_d = s1_d + s2_d&lt;br /&gt;
&lt;br /&gt;
# rekonstrukcja bazująca na współczynnikach otzrzynmanych dla 2sek fragmentu sygnału&lt;br /&gt;
n=np.arange(0,len(t_d),1)&lt;br /&gt;
s_rekonstrukcja_dluga = np.zeros(len(t_d)) &lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja_dluga += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
py.plot(t_d,(s_rekonstrukcja_dluga),'gx-',markersize = 8)&lt;br /&gt;
py.plot(t_d,s_d,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Przykład:=====&lt;br /&gt;
Oblicz współczynniki numerycznie korzystając z &amp;lt;tt&amp;gt;numpy.fft.fft&amp;lt;/tt&amp;gt;, porównaj z otrzymanymi analitycznie. Zrób wykresy funkcji i wartości bezwzględnej transformaty. Dla funkcji ''f'' z poprzedniego przykładu danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt; f(t)=|t| &amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-1, 1]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1,&lt;br /&gt;
&lt;br /&gt;
Obliczamy współczynniki i robimy wykres:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def f1():&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co 0.1	'''&lt;br /&gt;
	dt = 0.1	&lt;br /&gt;
	t = np.arange(-1,1,dt)&lt;br /&gt;
	s = np.abs(t)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
Fs = 10.0&lt;br /&gt;
(s,t) = f1() #generuję sygnał&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.stem(t,s)&lt;br /&gt;
&lt;br /&gt;
S=FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
F = FFT.fftfreq(len(S),Fs) # obliczam skalę częstości &lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.stem(F,np.abs(S)/len(s)) # wykreślam widmo amplitudowe&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Porównujemy wyniki z wynikami analitycznymi:&lt;br /&gt;
* &amp;lt;math&amp;gt; f(t) = |cos(t)|&amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-\pi, \pi]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
==== Efekt nieciągłości funkcji ====&lt;br /&gt;
* Wygenerować sinusoidę o następujących własnościach: f=10 Hz, T=1, Fs=100 Hz, i fazie = 1;&lt;br /&gt;
* Przy pomocy subplotów proszę sporządzić rysunek zgodnie z ponższym opisem:&lt;br /&gt;
** subplot(2,2,1): przebieg sygnału w czasie &lt;br /&gt;
** subplot(2,2,2): moduł jego transformaty Fouriera (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(len(s), 1/Fs)&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; to nasz sygnał),&lt;br /&gt;
** subplot(2,2,3): Proszę wykreślić trzykrotnie periodycznie powielony oryginalny sygnał. Można go skonstruować wywołując funkcję: &amp;lt;tt&amp;gt;s_period = np.concatenate((s,s,s))&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** subplot(2,2,4): moduł transformaty Fouriera &amp;lt;tt&amp;gt;s_period&amp;lt;/tt&amp;gt; (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(3*len(s), 1/Fs)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Powtórz te same kroki dla sinusa o częstości 10.3 Hz.&lt;br /&gt;
Pytania:&lt;br /&gt;
# Czym różnią się przedłużenia sinusoidy 10 Hz od sinusoidy 10.3 Hz? Proszę zwrócić uwagę na miejsca sklejania sygnałów. &amp;lt;!--Porównaj z wynikami otrzymanymi w zagadnieniu '''Rekonstrukcja na dłuższym odcinku czasu'''.--&amp;gt;&lt;br /&gt;
# Skąd bierze się widoczna różnica w widmie sinusoidy 10Hz i 10.3 Hz? &lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s,t) = sin(f = 10.3, T =1, Fs = 100, phi = 1)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s))&lt;br /&gt;
t_period = np.arange(0,3,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Długość sygnału a rozdzielczość widma FFT ====&lt;br /&gt;
Z dotychczasowych rozważań o transformacie Fouriera ograniczonych w czasie sygnałów dyskretnych wynika, że w widmie reprezentowane są częstości od &amp;lt;math&amp;gt;-F_N&amp;lt;/math&amp;gt; do &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; to częstości Nyquista. Dostępnych binów częstości jest ''N'' - tyle samo ile obserwowanych punktów sygnału. Zatem zwiększenie długości sygnału w czasie poprawia &amp;quot;rozdzielczość&amp;quot;  reprezentacji częstotliwościowej sygnału. &lt;br /&gt;
&lt;br /&gt;
Załóżmy, że dysponujemy jedynie sekwencją ''N'' próbek pewnego sygnału. Rozważymy teraz jakie można przyjąć strategie przedłużania tego sygnału w celu zwiększenia gęstości binów częstotliwościowych i jakie te strategie mają konsekwencje.&lt;br /&gt;
&lt;br /&gt;
=====Przedłużenie przez periodyczną replikację =====&lt;br /&gt;
Rozważając poprzednie przykłady zauważyliśmy, że FFT &amp;quot;widzi&amp;quot; sygnał tak jakby to była nieskończona periodyczna replikacja fragmentu sygnału podanego na wejście. Zatem najbardziej naturalną formą przedłużenia sygnału może wydawać się postępowanie zgodnie z tym sposobem widzenia i dołożenie do sygnału kolejnych segmentów zawierających kopie analizowanego fragmentu sygnału. Zbadajmy empirycznie efekty takiego podejścia. &lt;br /&gt;
&lt;br /&gt;
* Proszę wytworzyć i wykreślić sinusoidy o częstościach 15 i 20 Hz, trwające 0.1s i próbkowane 100Hz. &lt;br /&gt;
** Ile próbek sygnału dostajemy?&lt;br /&gt;
** Proszę obliczyć transformatę Fouriera. Ile punktów w widmie amplitudowym otrzymujemy? Dla jakich cżęstości mamy biny?&lt;br /&gt;
** Proszę skonstruować sygnał będący złożeniem 10 kopii oryginalnego sygnału. &lt;br /&gt;
Jest to 10-krotnie dłuższy fragment sygnału, którego wersję nieskończoną opisują współczynniki obliczone przez transformatę Fouriera. Transformata policzona z takiego wydłużonego odcinak ma 10-krotnie więcej binów. W szczególności zawiera on bin 15Hz. Proszę porównać wykresy widma amplitudowego otrzymanego dla wersji krótkiej i przedłużonej sygnału. Czy wynik jest zaskakujący? Jak go można zrozumieć?&lt;br /&gt;
 * Sygnał przedłużony periodycznie nie zawiera żadnej dodatkowej informacji względem pojedynczego okresu!&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s,s,s,s,s,s,s,s))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Przedłużanie sygnału zerami =====&lt;br /&gt;
Inną popularną metodą na zwiększanie ilości binów w transformacie Fouriera jest przedłużanie sygnału zerami (zero-padding). Jest to szczególny przypadek następującego podejścia: Nasz &amp;quot;prawdziwy&amp;quot; sygnał jest długi. Oglądamy go przez prostokątne okno, które ma wartość 1 na odcinku czasu dla którego próbki mamy dostępne i 0 dla pozostałego czasu (więcej o różnych oknach będzie na kolejnych zajęciach). W efekcie możemy myśleć, że oglądany przez nas sygnał to efekt przemnożenia &amp;quot;prawdziwego&amp;quot; sygnału przez okno. Efekty takiego przedłużania proszę zbadać przy użyciu poniższego kodu. &lt;br /&gt;
* Jak można zinterpretować wyniki tego eksperymentu w świetle [[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|twierdzenia o splocie]]?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,z,z,z,z,z,z,z,z,z))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S))&lt;br /&gt;
py.stem(F,np.abs(S)/len(S),linefmt='r-', markerfmt='ro')&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4144</id>
		<title>Ćwiczenia 2 2</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4144"/>
		<updated>2015-09-30T12:27:56Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Zadania */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Zadania ===&lt;br /&gt;
&lt;br /&gt;
==== Współczynniki obliczane przez FFT ====&lt;br /&gt;
Najprostsza sytuacja: Badamy współczynniki zwracane przez &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt; dla sinusoid o różnych częstościach. Wykorzystujemy funkcje do generacji sygnałów napisane na poprzednich zajęciach.&lt;br /&gt;
&lt;br /&gt;
* Proszę kolejno wygenerować sinusoidy o długości 1s próbkowaną 128Hz i częstościach 1,10,30, 64  i  0 Hz. Dla tych sinusoid proszę policzyć transformaty Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wyglądają otrzymane wykresy?&lt;br /&gt;
** Czy coś szczególnego dzieje się dla częstości 0 i 64Hz? Czy w tych skrajnych przypadkach faza sygnału ma wpływ na wynik transformaty? &lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał delta położony w sekundzie 0,5 na odcinku czasu o długości 1s próbkowany 128Hz. Dla takiego sygnału proszę policzyć transformatę Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wygląda transformata funkcji delta? Jakie częstości w sobie zawiera?&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
# skrypt implemetujący polecenia w sekcji&lt;br /&gt;
# Współczynniki obliczane przez FFT&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
def delta(t0=0.5, T=1  ,Fs = 128):&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	d = np.zeros(len(t))&lt;br /&gt;
	d[np.ceil(t0*Fs)]=1&lt;br /&gt;
	return (d,t)&lt;br /&gt;
 &lt;br /&gt;
# do pytania 1&lt;br /&gt;
(s,t) = sin(f=2,T=1,Fs=10,phi=np.pi/2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
print S&lt;br /&gt;
# na wydruku należy zauważyć, że wsółczynniki są zespolone i parami sprzężone&lt;br /&gt;
&lt;br /&gt;
# do pytania 2&lt;br /&gt;
(s,t) = sin(f=1,T=1,Fs=128,phi=np.pi/3) # f=0,10,30,64&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&lt;br /&gt;
# do pytania 3&lt;br /&gt;
(s,t) = delta(t0=0.5, T=1  ,Fs = 128)&lt;br /&gt;
&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(2)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Rekonstrukcja sygnału ze współczynników =====&lt;br /&gt;
Reprezentacja sygnałów w dziedzinie częstości jest dualna do reprezentacji  w dziedzinie czasu. To znaczy, że jedną reprezentację można przekształcić w drugą. Do przejścia z dziedziny czasu do częstości używaliśmy transformaty Fouriera (zaimplemantowanej w &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt;). Przejścia z dziedziny częstości do czasu dokonujemy przy pomocy odwrotnej transformaty Fouriera (zaimplementowanej jako &amp;lt;tt&amp;gt;ifft&amp;lt;/tt&amp;gt;. Mając (zespolone) współczynniki w dziedzinie częstości dla pewnego sygnału,możemy odzyskać jego przebieg czasowy.&lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał &amp;lt;math&amp;gt;s(t) = \sin(2\pi t \cdot 1)+\sin\left(2 \pi  t \cdot 3+\frac{\pi}{5}\right) &amp;lt;/math&amp;gt; o długości 2,5s próbkowany 10Hz, obliczyć jego transformatę Fouriera, a następnie zrekonstruować przebieg czasowy. Sygnał oryginalny i zrekonstruowany wykreślić na jednym rysunku.  Korzystając z naszych funkcji generację sygnału można zapisać tak:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
(s1,t) = sin(f=1, T=2.5, Fs=10, phi=0)&lt;br /&gt;
(s2,t) = sin(f=3, T=2.5, Fs=10, phi=np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Dla porównania proszę zrekonstruować sygnał korzystając jawnie z postaci odwrotnej transformaty Fouriera danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;x(n)=\frac{1}{N} \sum_{k=0}^{N-1} S[k] \cdot \exp\left(2j \pi n\frac{ k}{N}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
:Zwróćmy uwagę, że ''n'' w powyższym wzorze to indeksy punktów czasu, zatem wiążą się one z czasem zwracanym przez nasze funkcje następująco:&lt;br /&gt;
:&amp;lt;tt&amp;gt;n=np.arange(0,len(t),1)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
zatem kod rekonstruujący może być np. taki:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
n=np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
&lt;br /&gt;
def f1(dt):&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co dt	'''&lt;br /&gt;
	t = np.arange(0,2,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*t)+np.sin(2*np.pi*3*t+np.pi/5)#np.abs(t)#&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
dt = 0.1	&lt;br /&gt;
Fs = 1.0/dt&lt;br /&gt;
&lt;br /&gt;
(s1,t) = sin(f=1,T=2.5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2,t) = sin(f=3,T=2.5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
S = FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
N = len(t)&lt;br /&gt;
&lt;br /&gt;
s_ifft = FFT.ifft(S)&lt;br /&gt;
&lt;br /&gt;
n = np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.plot(t,s_ifft,'bo',markersize = 3 )&lt;br /&gt;
py.plot(t,(s_rekonstrukcja),'gx',markersize = 8)&lt;br /&gt;
py.plot(t,s,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Rekonstrukcja na dłuższym odcinku czasu:=====&lt;br /&gt;
Korzystając z wyników poprzedniego polecenia proszę porównać wykres funkcji zadanych wzorami dla odcinak czasu o długości 5s i rekonstrukcję sygnału o długości 5s otrzymanego ze współczynników Fouriera obliczonych dla 2,5s  odcinak czasu.&lt;br /&gt;
* Na jakim odcinku czasu sygnały są zgodne?&lt;br /&gt;
* Co dzieje się na dalszym odcinku czasu?&lt;br /&gt;
 *&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
dalszy ciąg poprzedniego kodu:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.figure(2)&lt;br /&gt;
(s1_d,t_d) = sin(f=1,T=5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2_d,t_d) = sin(f=3,T=5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s_d = s1_d + s2_d&lt;br /&gt;
&lt;br /&gt;
# rekonstrukcja bazująca na współczynnikach otzrzynmanych dla 2sek fragmentu sygnału&lt;br /&gt;
n=np.arange(0,len(t_d),1)&lt;br /&gt;
s_rekonstrukcja_dluga = np.zeros(len(t_d)) &lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja_dluga += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
py.plot(t_d,(s_rekonstrukcja_dluga),'gx-',markersize = 8)&lt;br /&gt;
py.plot(t_d,s_d,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Przykład:=====&lt;br /&gt;
Oblicz współczynniki numerycznie korzystając z &amp;lt;tt&amp;gt;numpy.fft.fft&amp;lt;/tt&amp;gt;, porównaj z otrzymanymi analitycznie. Zrób wykresy funkcji i wartości bezwzględnej transformaty. Dla funkcji ''f'' z poprzedniego przykładu danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt; f(t)=|t| &amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-1, 1]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1,&lt;br /&gt;
&lt;br /&gt;
Obliczamy współczynniki i robimy wykres:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def f1():&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co 0.1	'''&lt;br /&gt;
	dt = 0.1	&lt;br /&gt;
	t = np.arange(-1,1,dt)&lt;br /&gt;
	s = np.abs(t)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
Fs = 10.0&lt;br /&gt;
(s,t) = f1() #generuję sygnał&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.stem(t,s)&lt;br /&gt;
&lt;br /&gt;
S=FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
F = FFT.fftfreq(len(S),Fs) # obliczam skalę częstości &lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.stem(F,np.abs(S)/len(s)) # wykreślam widmo amplitudowe&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Porównujemy wyniki z wynikami analitycznymi:&lt;br /&gt;
* &amp;lt;math&amp;gt; f(t) = |cos(t)|&amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-\pi, \pi]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
==== Efekt nieciągłości funkcji ====&lt;br /&gt;
* Wygenerować sinusoidę o następujących własnościach: f=10 Hz, T=1, Fs=100 Hz, i fazie = 1;&lt;br /&gt;
* Przy pomocy subplotów proszę sporządzić rysunek zgodnie z ponższym opisem:&lt;br /&gt;
** subplot(2,2,1): przebieg sygnału w czasie &lt;br /&gt;
** subplot(2,2,2): moduł jego transformaty Fouriera (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(len(s), 1/Fs)&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; to nasz sygnał),&lt;br /&gt;
** subplot(2,2,3): Proszę wykreślić trzykrotnie periodycznie powielony oryginalny sygnał. Można go skonstruować wywołując funkcję: &amp;lt;tt&amp;gt;s_period = np.concatenate((s,s,s))&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** subplot(2,2,4): moduł transformaty Fouriera &amp;lt;tt&amp;gt;s_period&amp;lt;/tt&amp;gt; (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(3*len(s), 1/Fs)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Powtórz te same kroki dla sinusa o częstości 10.3 Hz.&lt;br /&gt;
Pytania:&lt;br /&gt;
# Czym różnią się przedłużenia sinusoidy 10Hz od sinusoidy 10.3Hz? Proszę zwrócić uwagę na miejsca sklejania sygnałów.Porównaj z wynikami otrzymanymi w zagadnieniu '''Rekonstrukcja na dłuższym odcinku czasu'''.&lt;br /&gt;
# Skąd bierze się widoczna różnica w widmie sinusoidy 10Hz i 10.3Hz? &lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s,t) = sin(f = 10.3, T =1, Fs = 100, phi = 1)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s))&lt;br /&gt;
t_period = np.arange(0,3,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Długość sygnału a rozdzielczość widma FFT ====&lt;br /&gt;
Z dotychczasowych rozważań o transformacie Fouriera ograniczonych w czasie sygnałów dyskretnych wynika, że w widmie reprezentowane są częstości od &amp;lt;math&amp;gt;-F_N&amp;lt;/math&amp;gt; do &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; to częstości Nyquista. Dostępnych binów częstości jest ''N'' - tyle samo ile obserwowanych punktów sygnału. Zatem zwiększenie długości sygnału w czasie poprawia &amp;quot;rozdzielczość&amp;quot;  reprezentacji częstotliwościowej sygnału. &lt;br /&gt;
&lt;br /&gt;
Załóżmy, że dysponujemy jedynie sekwencją ''N'' próbek pewnego sygnału. Rozważymy teraz jakie można przyjąć strategie przedłużania tego sygnału w celu zwiększenia gęstości binów częstotliwościowych i jakie te strategie mają konsekwencje.&lt;br /&gt;
&lt;br /&gt;
=====Przedłużenie przez periodyczną replikację =====&lt;br /&gt;
Rozważając poprzednie przykłady zauważyliśmy, że FFT &amp;quot;widzi&amp;quot; sygnał tak jakby to była nieskończona periodyczna replikacja fragmentu sygnału podanego na wejście. Zatem najbardziej naturalną formą przedłużenia sygnału może wydawać się postępowanie zgodnie z tym sposobem widzenia i dołożenie do sygnału kolejnych segmentów zawierających kopie analizowanego fragmentu sygnału. Zbadajmy empirycznie efekty takiego podejścia. &lt;br /&gt;
&lt;br /&gt;
* Proszę wytworzyć i wykreślić sinusoidy o częstościach 15 i 20 Hz, trwające 0.1s i próbkowane 100Hz. &lt;br /&gt;
** Ile próbek sygnału dostajemy?&lt;br /&gt;
** Proszę obliczyć transformatę Fouriera. Ile punktów w widmie amplitudowym otrzymujemy? Dla jakich cżęstości mamy biny?&lt;br /&gt;
** Proszę skonstruować sygnał będący złożeniem 10 kopii oryginalnego sygnału. &lt;br /&gt;
Jest to 10-krotnie dłuższy fragment sygnału, którego wersję nieskończoną opisują współczynniki obliczone przez transformatę Fouriera. Transformata policzona z takiego wydłużonego odcinak ma 10-krotnie więcej binów. W szczególności zawiera on bin 15Hz. Proszę porównać wykresy widma amplitudowego otrzymanego dla wersji krótkiej i przedłużonej sygnału. Czy wynik jest zaskakujący? Jak go można zrozumieć?&lt;br /&gt;
 * Sygnał przedłużony periodycznie nie zawiera żadnej dodatkowej informacji względem pojedynczego okresu!&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s,s,s,s,s,s,s,s))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Przedłużanie sygnału zerami =====&lt;br /&gt;
Inną popularną metodą na zwiększanie ilości binów w transformacie Fouriera jest przedłużanie sygnału zerami (zero-padding). Jest to szczególny przypadek następującego podejścia: Nasz &amp;quot;prawdziwy&amp;quot; sygnał jest długi. Oglądamy go przez prostokątne okno, które ma wartość 1 na odcinku czasu dla którego próbki mamy dostępne i 0 dla pozostałego czasu (więcej o różnych oknach będzie na kolejnych zajęciach). W efekcie możemy myśleć, że oglądany przez nas sygnał to efekt przemnożenia &amp;quot;prawdziwego&amp;quot; sygnału przez okno. Efekty takiego przedłużania proszę zbadać przy użyciu poniższego kodu. &lt;br /&gt;
* Jak można zinterpretować wyniki tego eksperymentu w świetle [[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|twierdzenia o splocie]]?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,z,z,z,z,z,z,z,z,z))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S))&lt;br /&gt;
py.stem(F,np.abs(S)/len(S),linefmt='r-', markerfmt='ro')&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4143</id>
		<title>Ćwiczenia 2 2</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4143"/>
		<updated>2015-09-30T12:26:50Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Zadania */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Zadania ===&lt;br /&gt;
&lt;br /&gt;
==== Współczynniki obliczane przez FFT ====&lt;br /&gt;
Najprostsza sytuacja: Badamy współczynniki zwracane przez &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt; dla sinusoid o różnych częstościach. Wykorzystujemy funkcje do generacji sygnałów napisane na poprzednich zajęciach.&lt;br /&gt;
&lt;br /&gt;
* Proszę kolejno wygenerować sinusoidy o długości 1s próbkowaną 128Hz i częstościach 1,10,30, 64  i  0 Hz. Dla tych sinusoid proszę policzyć transformaty Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wyglądają otrzymane wykresy?&lt;br /&gt;
** Czy coś szczególnego dzieje się dla częstości 0 i 64Hz? Czy w tych skrajnych przypadkach faza sygnału ma wpływ na wynik transformaty? &lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał delta położony w sekundzie 0,5 na odcinku czasu o długości 1s próbkowany 128Hz. Dla takiego sygnału proszę policzyć transformatę Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wygląda transformata funkcji delta? Jakie częstości w sobie zawiera?&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
# skrypt implemetujący polecenia w sekcji&lt;br /&gt;
# Współczynniki obliczane przez FFT&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
def delta(t0=0.5, T=1  ,Fs = 128):&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	d = np.zeros(len(t))&lt;br /&gt;
	d[np.ceil(t0*Fs)]=1&lt;br /&gt;
	return (d,t)&lt;br /&gt;
 &lt;br /&gt;
# do pytania 1&lt;br /&gt;
(s,t) = sin(f=2,T=1,Fs=10,phi=np.pi/2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
print S&lt;br /&gt;
# na wydruku należy zauważyć, że wsółczynniki są zespolone i parami sprzężone&lt;br /&gt;
&lt;br /&gt;
# do pytania 2&lt;br /&gt;
(s,t) = sin(f=1,T=1,Fs=128,phi=np.pi/3) # f=0,10,30,64&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&lt;br /&gt;
# do pytania 3&lt;br /&gt;
(s,t) = delta(t0=0.5, T=1  ,Fs = 128)&lt;br /&gt;
&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(2)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Rekonstrukcja sygnału ze współczynników =====&lt;br /&gt;
Reprezentacja sygnałów w dziedzinie częstości jest dualna do reprezentacji  w dziedzinie czasu. To znaczy, że jedną reprezentację można przekształcić w drugą. Do przejścia z dziedziny czasu do częstości używaliśmy transformaty Fouriera (zaimplemantowanej w &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt;). Przejścia z dziedziny częstości do czasu dokonujemy przy pomocy odwrotnej transformaty Fouriera (zaimplementowanej jako &amp;lt;tt&amp;gt;ifft&amp;lt;/tt&amp;gt;. Mając (zespolone) współczynniki w dziedzinie częstości dla pewnego sygnału,możemy odzyskać jego przebieg czasowy.&lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał &amp;lt;math&amp;gt;s(t) = \sin(2\pi t \cdot 1)+\sin\left(2 \pi  t \cdot 3+\frac{\pi}{5}\right) &amp;lt;/math&amp;gt; o długości 2,5s próbkowany 10Hz, obliczyć jego transformatę Fouriera, a następnie zrekonstruować przebieg czasowy. Sygnał oryginalny i zrekonstruowany wykreślić na jednym rysunku.  Korzystając z naszych funkcji generację sygnału można zapisać tak:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
(s1,t) = sin(f=1, T=2.5, Fs=10, phi=0)&lt;br /&gt;
(s2,t) = sin(f=3, T=2.5, Fs=10, phi=np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Dla porównania proszę zrekonstruować sygnał korzystając jawnie z postaci odwrotnej transformaty Fouriera danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;x(n)=\frac{1}{N} \sum_{k=0}^{N-1} S[k] \cdot \exp\left(2j \pi n\frac{ k}{N}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
:Zwróćmy uwagę, że ''n'' w powyższym wzorze to indeksy punktów czasu, zatem wiążą się one z czasem zwracanym przez nasze funkcje następująco:&lt;br /&gt;
:&amp;lt;tt&amp;gt;n=np.arange(0,len(t),1)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
zatem kod rekonstruujący może być np. taki:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
n=np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
&lt;br /&gt;
def f1(dt):&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co dt	'''&lt;br /&gt;
	t = np.arange(0,2,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*t)+np.sin(2*np.pi*3*t+np.pi/5)#np.abs(t)#&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
dt = 0.1	&lt;br /&gt;
Fs = 1.0/dt&lt;br /&gt;
&lt;br /&gt;
(s1,t) = sin(f=1,T=2.5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2,t) = sin(f=3,T=2.5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
S = FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
N = len(t)&lt;br /&gt;
&lt;br /&gt;
s_ifft = FFT.ifft(S)&lt;br /&gt;
&lt;br /&gt;
n = np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.plot(t,s_ifft,'bo',markersize = 3 )&lt;br /&gt;
py.plot(t,(s_rekonstrukcja),'gx',markersize = 8)&lt;br /&gt;
py.plot(t,s,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Rekonstrukcja na dłuższym odcinku czasu:=====&lt;br /&gt;
Korzystając z wyników poprzedniego polecenia proszę porównać wykres funkcji zadanych wzorami dla odcinak czasu o długości 5s i rekonstrukcję sygnału o długości 5s otrzymanego ze współczynników Fouriera obliczonych dla 2,5s  odcinak czasu.&lt;br /&gt;
* Na jakim odcinku czasu sygnały są zgodne?&lt;br /&gt;
* Co dzieje się na dalszym odcinku czasu?&lt;br /&gt;
 *&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
dalszy ciąg poprzedniego kodu:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.figure(2)&lt;br /&gt;
(s1_d,t_d) = sin(f=1,T=5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2_d,t_d) = sin(f=3,T=5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s_d = s1_d + s2_d&lt;br /&gt;
&lt;br /&gt;
# rekonstrukcja bazująca na współczynnikach otzrzynmanych dla 2sek fragmentu sygnału&lt;br /&gt;
n=np.arange(0,len(t_d),1)&lt;br /&gt;
s_rekonstrukcja_dluga = np.zeros(len(t_d)) &lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja_dluga += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
py.plot(t_d,(s_rekonstrukcja_dluga),'gx-',markersize = 8)&lt;br /&gt;
py.plot(t_d,s_d,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Przykład:=====&lt;br /&gt;
Oblicz współczynniki numerycznie korzystając z &amp;lt;tt&amp;gt;numpy.fft.fft&amp;lt;/tt&amp;gt;, porównaj z otrzymanymi analitycznie. Zrób wykresy funkcji i wartości bezwzględnej transformaty. Dla funkcji ''f'' z poprzedniego przykładu danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt; f(t)=|t| &amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-1, 1]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1,&lt;br /&gt;
&lt;br /&gt;
Obliczamy współczynniki i robimy wykres:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def f1():&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co 0.1	'''&lt;br /&gt;
	dt = 0.1	&lt;br /&gt;
	t = np.arange(-1,1,dt)&lt;br /&gt;
	s = np.abs(t)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
Fs = 10.0&lt;br /&gt;
(s,t) = f1() #generuję sygnał&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.stem(t,s)&lt;br /&gt;
&lt;br /&gt;
S=FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
F = FFT.fftfreq(len(S),Fs) # obliczam skalę częstości &lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.stem(F,np.abs(S)/len(s)) # wykreślam widmo amplitudowe&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Porównujemy wyniki z wynikami analitycznymi:&lt;br /&gt;
* &amp;lt;math&amp;gt; f(t) = |cos(t)|&amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-\pi, \pi]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Efekt nieciągłości funkcji ====&lt;br /&gt;
* Wygenerować sinusoidę o następujących własnościach: f=10 Hz, T=1, Fs=100 Hz, i fazie = 1;&lt;br /&gt;
* Przy pomocy subplotów proszę sporządzić rysunek zgodnie z ponższym opisem:&lt;br /&gt;
** subplot(2,2,1): przebieg sygnału w czasie &lt;br /&gt;
** subplot(2,2,2): moduł jego transformaty Fouriera (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(len(s), 1/Fs)&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; to nasz sygnał),&lt;br /&gt;
** subplot(2,2,3): Proszę wykreślić trzykrotnie periodycznie powielony oryginalny sygnał. Można go skonstruować wywołując funkcję: &amp;lt;tt&amp;gt;s_period = np.concatenate((s,s,s))&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** subplot(2,2,4): moduł transformaty Fouriera &amp;lt;tt&amp;gt;s_period&amp;lt;/tt&amp;gt; (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(3*len(s), 1/Fs)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Powtórz te same kroki dla sinusa o częstości 10.3 Hz.&lt;br /&gt;
Pytania:&lt;br /&gt;
# Czym różnią się przedłużenia sinusoidy 10Hz od sinusoidy 10.3Hz? Proszę zwrócić uwagę na miejsca sklejania sygnałów.Porównaj z wynikami otrzymanymi w zagadnieniu '''Rekonstrukcja na dłuższym odcinku czasu'''.&lt;br /&gt;
# Skąd bierze się widoczna różnica w widmie sinusoidy 10Hz i 10.3Hz? &lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s,t) = sin(f = 10.3, T =1, Fs = 100, phi = 1)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s))&lt;br /&gt;
t_period = np.arange(0,3,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Długość sygnału a rozdzielczość widma FFT ====&lt;br /&gt;
Z dotychczasowych rozważań o transformacie Fouriera ograniczonych w czasie sygnałów dyskretnych wynika, że w widmie reprezentowane są częstości od &amp;lt;math&amp;gt;-F_N&amp;lt;/math&amp;gt; do &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; to częstości Nyquista. Dostępnych binów częstości jest ''N'' - tyle samo ile obserwowanych punktów sygnału. Zatem zwiększenie długości sygnału w czasie poprawia &amp;quot;rozdzielczość&amp;quot;  reprezentacji częstotliwościowej sygnału. &lt;br /&gt;
&lt;br /&gt;
Załóżmy, że dysponujemy jedynie sekwencją ''N'' próbek pewnego sygnału. Rozważymy teraz jakie można przyjąć strategie przedłużania tego sygnału w celu zwiększenia gęstości binów częstotliwościowych i jakie te strategie mają konsekwencje.&lt;br /&gt;
&lt;br /&gt;
=====Przedłużenie przez periodyczną replikację =====&lt;br /&gt;
Rozważając poprzednie przykłady zauważyliśmy, że FFT &amp;quot;widzi&amp;quot; sygnał tak jakby to była nieskończona periodyczna replikacja fragmentu sygnału podanego na wejście. Zatem najbardziej naturalną formą przedłużenia sygnału może wydawać się postępowanie zgodnie z tym sposobem widzenia i dołożenie do sygnału kolejnych segmentów zawierających kopie analizowanego fragmentu sygnału. Zbadajmy empirycznie efekty takiego podejścia. &lt;br /&gt;
&lt;br /&gt;
* Proszę wytworzyć i wykreślić sinusoidy o częstościach 15 i 20 Hz, trwające 0.1s i próbkowane 100Hz. &lt;br /&gt;
** Ile próbek sygnału dostajemy?&lt;br /&gt;
** Proszę obliczyć transformatę Fouriera. Ile punktów w widmie amplitudowym otrzymujemy? Dla jakich cżęstości mamy biny?&lt;br /&gt;
** Proszę skonstruować sygnał będący złożeniem 10 kopii oryginalnego sygnału. &lt;br /&gt;
Jest to 10-krotnie dłuższy fragment sygnału, którego wersję nieskończoną opisują współczynniki obliczone przez transformatę Fouriera. Transformata policzona z takiego wydłużonego odcinak ma 10-krotnie więcej binów. W szczególności zawiera on bin 15Hz. Proszę porównać wykresy widma amplitudowego otrzymanego dla wersji krótkiej i przedłużonej sygnału. Czy wynik jest zaskakujący? Jak go można zrozumieć?&lt;br /&gt;
 * Sygnał przedłużony periodycznie nie zawiera żadnej dodatkowej informacji względem pojedynczego okresu!&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s,s,s,s,s,s,s,s))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Przedłużanie sygnału zerami =====&lt;br /&gt;
Inną popularną metodą na zwiększanie ilości binów w transformacie Fouriera jest przedłużanie sygnału zerami (zero-padding). Jest to szczególny przypadek następującego podejścia: Nasz &amp;quot;prawdziwy&amp;quot; sygnał jest długi. Oglądamy go przez prostokątne okno, które ma wartość 1 na odcinku czasu dla którego próbki mamy dostępne i 0 dla pozostałego czasu (więcej o różnych oknach będzie na kolejnych zajęciach). W efekcie możemy myśleć, że oglądany przez nas sygnał to efekt przemnożenia &amp;quot;prawdziwego&amp;quot; sygnału przez okno. Efekty takiego przedłużania proszę zbadać przy użyciu poniższego kodu. &lt;br /&gt;
* Jak można zinterpretować wyniki tego eksperymentu w świetle [[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|twierdzenia o splocie]]?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,z,z,z,z,z,z,z,z,z))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S))&lt;br /&gt;
py.stem(F,np.abs(S)/len(S),linefmt='r-', markerfmt='ro')&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4142</id>
		<title>Ćwiczenia 2 2</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4142"/>
		<updated>2015-09-30T12:25:59Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Zadania */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Zadania ===&lt;br /&gt;
&lt;br /&gt;
==== Współczynniki obliczane przez FFT ====&lt;br /&gt;
Najprostsza sytuacja: Badamy współczynniki zwracane przez &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt; dla sinusoid o różnych częstościach. Wykorzystujemy funkcje do generacji sygnałów napisane na poprzednich zajęciach.&lt;br /&gt;
&lt;br /&gt;
* Proszę kolejno wygenerować sinusoidy o długości 1s próbkowaną 128Hz i częstościach 1,10,30, 64  i  0 Hz. Dla tych sinusoid proszę policzyć transformaty Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wyglądają otrzymane wykresy?&lt;br /&gt;
** Czy coś szczególnego dzieje się dla częstości 0 i 64Hz? Czy w tych skrajnych przypadkach faza sygnału ma wpływ na wynik transformaty? &lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał delta położony w sekundzie 0,5 na odcinku czasu o długości 1s próbkowany 128Hz. Dla takiego sygnału proszę policzyć transformatę Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wygląda transformata funkcji delta? Jakie częstości w sobie zawiera?&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
# skrypt implemetujący polecenia w sekcji&lt;br /&gt;
# Współczynniki obliczane przez FFT&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
def delta(t0=0.5, T=1  ,Fs = 128):&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	d = np.zeros(len(t))&lt;br /&gt;
	d[np.ceil(t0*Fs)]=1&lt;br /&gt;
	return (d,t)&lt;br /&gt;
 &lt;br /&gt;
# do pytania 1&lt;br /&gt;
(s,t) = sin(f=2,T=1,Fs=10,phi=np.pi/2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
print S&lt;br /&gt;
# na wydruku należy zauważyć, że wsółczynniki są zespolone i parami sprzężone&lt;br /&gt;
&lt;br /&gt;
# do pytania 2&lt;br /&gt;
(s,t) = sin(f=1,T=1,Fs=128,phi=np.pi/3) # f=0,10,30,64&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&lt;br /&gt;
# do pytania 3&lt;br /&gt;
(s,t) = delta(t0=0.5, T=1  ,Fs = 128)&lt;br /&gt;
&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(2)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Rekonstrukcja sygnału ze współczynników =====&lt;br /&gt;
Reprezentacja sygnałów w dziedzinie częstości jest dualna do reprezentacji  w dziedzinie czasu. To znaczy, że jedną reprezentację można przekształcić w drugą. Do przejścia z dziedziny czasu do częstości używaliśmy transformaty Fouriera (zaimplemantowanej w &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt;). Przejścia z dziedziny częstości do czasu dokonujemy przy pomocy odwrotnej transformaty Fouriera (zaimplementowanej jako &amp;lt;tt&amp;gt;ifft&amp;lt;/tt&amp;gt;. Mając (zespolone) współczynniki w dziedzinie częstości dla pewnego sygnału,możemy odzyskać jego przebieg czasowy.&lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał &amp;lt;math&amp;gt;s(t) = \sin(2\pi t \cdot 1)+\sin\left(2 \pi  t \cdot 3+\frac{\pi}{5}\right) &amp;lt;/math&amp;gt; o długości 2,5s próbkowany 10Hz, obliczyć jego transformatę Fouriera, a następnie zrekonstruować przebieg czasowy. Sygnał oryginalny i zrekonstruowany wykreślić na jednym rysunku.  Korzystając z naszych funkcji generację sygnału można zapisać tak:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
(s1,t) = sin(f=1, T=2.5, Fs=10, phi=0)&lt;br /&gt;
(s2,t) = sin(f=3, T=2.5, Fs=10, phi=np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Dla porównania proszę zrekonstruować sygnał korzystając jawnie z postaci odwrotnej transformaty Fouriera danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;x(n)=\frac{1}{N} \sum_{k=0}^{N-1} S[k] \cdot \exp\left(2j \pi n\frac{ k}{N}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
:Zwróćmy uwagę, że ''n'' w powyższym wzorze to indeksy punktów czasu, zatem wiążą się one z czasem zwracanym przez nasze funkcje następująco:&lt;br /&gt;
:&amp;lt;tt&amp;gt;n=np.arange(0,len(t),1)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
zatem kod rekonstruujący może być np. taki:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
n=np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
&lt;br /&gt;
def f1(dt):&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co dt	'''&lt;br /&gt;
	t = np.arange(0,2,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*t)+np.sin(2*np.pi*3*t+np.pi/5)#np.abs(t)#&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
dt = 0.1	&lt;br /&gt;
Fs = 1.0/dt&lt;br /&gt;
&lt;br /&gt;
(s1,t) = sin(f=1,T=2.5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2,t) = sin(f=3,T=2.5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
S = FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
N = len(t)&lt;br /&gt;
&lt;br /&gt;
s_ifft = FFT.ifft(S)&lt;br /&gt;
&lt;br /&gt;
n = np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.plot(t,s_ifft,'bo',markersize = 3 )&lt;br /&gt;
py.plot(t,(s_rekonstrukcja),'gx',markersize = 8)&lt;br /&gt;
py.plot(t,s,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Rekonstrukcja na dłuższym odcinku czasu:=====&lt;br /&gt;
Korzystając z wyników poprzedniego polecenia proszę porównać wykres funkcji zadanych wzorami dla odcinak czasu o długości 5s i rekonstrukcję sygnału o długości 5s otrzymanego ze współczynników Fouriera obliczonych dla 2,5s  odcinak czasu.&lt;br /&gt;
* Na jakim odcinku czasu sygnały są zgodne?&lt;br /&gt;
* Co dzieje się na dalszym odcinku czasu?&lt;br /&gt;
 *&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
dalszy ciąg poprzedniego kodu:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.figure(2)&lt;br /&gt;
(s1_d,t_d) = sin(f=1,T=5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2_d,t_d) = sin(f=3,T=5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s_d = s1_d + s2_d&lt;br /&gt;
&lt;br /&gt;
# rekonstrukcja bazująca na współczynnikach otzrzynmanych dla 2sek fragmentu sygnału&lt;br /&gt;
n=np.arange(0,len(t_d),1)&lt;br /&gt;
s_rekonstrukcja_dluga = np.zeros(len(t_d)) &lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja_dluga += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
py.plot(t_d,(s_rekonstrukcja_dluga),'gx-',markersize = 8)&lt;br /&gt;
py.plot(t_d,s_d,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Przykład:=====&lt;br /&gt;
Oblicz współczynniki numerycznie korzystając z &amp;lt;tt&amp;gt;numpy.fft.fft&amp;lt;/tt&amp;gt;, porównaj z otrzymanymi analitycznie. Zrób wykresy funkcji i wartości bezwzględnej transformaty. Dla funkcji ''f'' z poprzedniego przykładu danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt; f(t)=|t| &amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-1, 1]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1,&lt;br /&gt;
&lt;br /&gt;
Obliczamy współczynniki i robimy wykres:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def f1():&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co 0.1	'''&lt;br /&gt;
	dt = 0.1	&lt;br /&gt;
	t = np.arange(-1,1,dt)&lt;br /&gt;
	s = np.abs(t)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
Fs = 10.0&lt;br /&gt;
(s,t) = f1() #generuję sygnał&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.stem(t,s)&lt;br /&gt;
&lt;br /&gt;
S=FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
F = FFT.fftfreq(len(S),Fs) # obliczam skalę częstości &lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.stem(F,np.abs(S)/len(s)) # wykreślam widmo amplitudowe&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Porównujemy wyniki z wynikami analitycznymi:&lt;br /&gt;
* &amp;lt;math&amp;gt; f(t) = |cos(t)|&amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-\pi, \pi]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Efekt nieciągłości funkcji ====&lt;br /&gt;
* Wygenerować sinusoidę o następujących własnościach: f=10 Hz, T=1, Fs=100 Hz, i fazie = 1;&lt;br /&gt;
* Przy pomocy subplotów proszę sporządzić rysunek zgodnie z ponższym opisem:&lt;br /&gt;
** subplot(2,2,1): przebieg sygnału w czasie &lt;br /&gt;
** subplot(2,2,2): moduł jego transformaty Fouriera (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(len(s), 1/Fs)&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; to nasz sygnał),&lt;br /&gt;
** subplot(2,2,3): Proszę wykreślić trzykrotnie periodycznie powielony oryginalny sygnał. Można go skonstruować wywołując funkcję: &amp;lt;tt&amp;gt;s_period = np.concatenate((s,s,s))&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** subplot(2,2,4): moduł transformaty Fouriera &amp;lt;tt&amp;gt;s_period&amp;lt;/tt&amp;gt; (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(3*len(s), 1/Fs)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Powtórz te same kroki dla sinusa o częstości 10.3 Hz.&lt;br /&gt;
Pytania:&lt;br /&gt;
# Czym różnią się przedłużenia sinusoidy 10Hz od sinusoidy 10.3Hz? Proszę zwrócić uwagę na miejsca sklejania sygnałów.Porównaj z wynikami otrzymanymi w zagadnieniu '''Rekonstrukcja na dłuższym odcinku czasu'''.&lt;br /&gt;
# Skąd bierze się widoczna różnica w widmie sinusoidy 10Hz i 10.3Hz? &lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s,t) = sin(f = 10.3, T =1, Fs = 100, phi = 1)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s))&lt;br /&gt;
t_period = np.arange(0,3,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Długość sygnału a rozdzielczość widma FFT ====&lt;br /&gt;
Z dotychczasowych rozważań o transformacie Fouriera ograniczonych w czasie sygnałów dyskretnych wynika, że w widmie reprezentowane są częstości od &amp;lt;math&amp;gt;-F_N&amp;lt;/math&amp;gt; do &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; to częstości Nyquista. Dostępnych binów częstości jest ''N'' - tyle samo ile obserwowanych punktów sygnału. Zatem zwiększenie długości sygnału w czasie poprawia &amp;quot;rozdzielczość&amp;quot;  reprezentacji częstotliwościowej sygnału. &lt;br /&gt;
&lt;br /&gt;
Załóżmy, że dysponujemy jedynie sekwencją ''N'' próbek pewnego sygnału. Rozważymy teraz jakie można przyjąć strategie przedłużania tego sygnału w celu zwiększenia gęstości binów częstotliwościowych i jakie te strategie mają konsekwencje.&lt;br /&gt;
&lt;br /&gt;
=====Przedłużenie przez periodyczną replikację =====&lt;br /&gt;
Rozważając poprzednie przykłady zauważyliśmy, że FFT &amp;quot;widzi&amp;quot; sygnał tak jakby to była nieskończona periodyczna replikacja fragmentu sygnału podanego na wejście. Zatem najbardziej naturalną formą przedłużenia sygnału może wydawać się postępowanie zgodnie z tym sposobem widzenia i dołożenie do sygnału kolejnych segmentów zawierających kopie analizowanego fragmentu sygnału. Zbadajmy empirycznie efekty takiego podejścia. &lt;br /&gt;
&lt;br /&gt;
* Proszę wytworzyć i wykreślić sinusoidy o częstościach 15 i 20 Hz, trwające 0.1s i próbkowane 100Hz. &lt;br /&gt;
** Ile próbek sygnału dostajemy?&lt;br /&gt;
** Proszę obliczyć transformatę Fouriera. Ile punktów w widmie amplitudowym otrzymujemy? Dla jakich cżęstości mamy biny?&lt;br /&gt;
** Proszę skonstruować sygnał będący złożeniem 10 kopii oryginalnego sygnału. &lt;br /&gt;
Jest to 10-krotnie dłuższy fragment sygnału, którego wersję nieskończoną opisują współczynniki obliczone przez transformatę Fouriera. Transformata policzona z takiego wydłużonego odcinak ma 10-krotnie więcej binów. W szczególności zawiera on bin 15Hz. Proszę porównać wykresy widma amplitudowego otrzymanego dla wersji krótkiej i przedłużonej sygnału. Czy wynik jest zaskakujący? Jak go można zrozumieć?&lt;br /&gt;
 * Sygnał przedłużony periodycznie nie zawiera żadnej dodatkowej informacji względem pojedynczego okresu!&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s,s,s,s,s,s,s,s))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Przedłużanie sygnału zerami =====&lt;br /&gt;
Inną popularną metodą na zwiększanie ilości binów w transformacie Fouriera jest przedłużanie sygnału zerami (zero-padding). Jest to szczególny przypadek następującego podejścia: Nasz &amp;quot;prawdziwy&amp;quot; sygnał jest długi. Oglądamy go przez prostokątne okno, które ma wartość 1 na odcinku czasu dla którego próbki mamy dostępne i 0 dla pozostałego czasu (więcej o różnych oknach będzie na kolejnych zajęciach). W efekcie możemy myśleć, że oglądany przez nas sygnał to efekt przemnożenia &amp;quot;prawdziwego&amp;quot; sygnału przez okno. Efekty takiego przedłużania proszę zbadać przy użyciu poniższego kodu. &lt;br /&gt;
* Jak można zinterpretować wyniki tego eksperymentu w świetle [[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|twierdzenia o splocie]]?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,z,z,z,z,z,z,z,z,z))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S))&lt;br /&gt;
py.stem(F,np.abs(S)/len(S),linefmt='r-', markerfmt='ro')&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4141</id>
		<title>Ćwiczenia 2 2</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2_2&amp;diff=4141"/>
		<updated>2015-09-30T12:15:25Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Współczynniki obliczane przez FFT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Zadania ===&lt;br /&gt;
&lt;br /&gt;
==== Współczynniki obliczane przez FFT ====&lt;br /&gt;
Najprostsza sytuacja: Badamy współczynniki zwracane przez &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt; dla sinusoid o różnych częstościach. Wykorzystujemy funkcje do generacji sygnałów napisane na poprzednich zajęciach.&lt;br /&gt;
&lt;br /&gt;
* Proszę kolejno wygenerować sinusoidy o długości 1s próbkowaną 128Hz i częstościach 1,10,30, 64  i  0 Hz. Dla tych sinusoid proszę policzyć transformaty Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wyglądają otrzymane wykresy?&lt;br /&gt;
** Czy coś szczególnego dzieje się dla częstości 0 i 64Hz? Czy w tych skrajnych przypadkach faza sygnału ma wpływ na wynik transformaty? &lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał delta położony w sekundzie 0,5 na odcinku czasu o długości 1s próbkowany 128Hz. Dla takiego sygnału proszę policzyć transformatę Fouriera i wykreślić zarówno sygnały jak i wartość bezwzględne otrzymanych współczynników.&lt;br /&gt;
** Jak wygląda transformata funkcji delta? Jakie częstości w sobie zawiera?&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
# skrypt implemetujący polecenia w sekcji&lt;br /&gt;
# Współczynniki obliczane przez FFT&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
 &lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
def delta(t0=0.5, T=1  ,Fs = 128):&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	d = np.zeros(len(t))&lt;br /&gt;
	d[np.ceil(t0*Fs)]=1&lt;br /&gt;
	return (d,t)&lt;br /&gt;
 &lt;br /&gt;
# do pytania 1&lt;br /&gt;
(s,t) = sin(f=2,T=1,Fs=10,phi=np.pi/2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
print S&lt;br /&gt;
# na wydruku należy zauważyć, że wsółczynniki są zespolone i parami sprzężone&lt;br /&gt;
&lt;br /&gt;
# do pytania 2&lt;br /&gt;
(s,t) = sin(f=1,T=1,Fs=128,phi=np.pi/3) # f=0,10,30,64&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&lt;br /&gt;
# do pytania 3&lt;br /&gt;
(s,t) = delta(t0=0.5, T=1  ,Fs = 128)&lt;br /&gt;
&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
py.figure(2)&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.plot(t,s,'o')&lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.plot(np.abs(S),'o')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Rekonstrukcja sygnału ze współczynników =====&lt;br /&gt;
Reprezentacja sygnałów w dziedzinie częstości jest dualna do reprezentacji  w dziedzinie czasu. To znaczy, że jedną reprezentację można przekształcić w drugą. Do przejścia z dziedziny czasu do częstości używaliśmy transformaty Fouriera (zaimplemantowanej w &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt;). Przejścia z dziedziny częstości do czasu dokonujemy przy pomocy odwrotnej transformaty Fouriera (zaimplementowanej jako &amp;lt;tt&amp;gt;ifft&amp;lt;/tt&amp;gt;. Mając (zespolone) współczynniki w dziedzinie częstości dla pewnego sygnału,możemy odzyskać jego przebieg czasowy.&lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować sygnał &amp;lt;math&amp;gt;s(t) = \sin(2\pi t \cdot 1)+\sin\left(2 \pi  t \cdot 3+\frac{\pi}{5}\right) &amp;lt;/math&amp;gt; o długości 2,5s próbkowany 10Hz, obliczyć jego transformatę Fouriera, a następnie zrekonstruować przebieg czasowy. Sygnał oryginalny i zrekonstruowany wykreślić na jednym rysunku.  Korzystając z naszych funkcji generację sygnału można zapisać tak:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
(s1,t) = sin(f=1, T=2.5, Fs=10, phi=0)&lt;br /&gt;
(s2,t) = sin(f=3, T=2.5, Fs=10, phi=np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Dla porównania proszę zrekonstruować sygnał korzystając jawnie z postaci odwrotnej transformaty Fouriera danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt;x(n)=\frac{1}{N} \sum_{k=0}^{N-1} S[k] \cdot \exp\left(2j \pi n\frac{ k}{N}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
:Zwróćmy uwagę, że ''n'' w powyższym wzorze to indeksy punktów czasu, zatem wiążą się one z czasem zwracanym przez nasze funkcje następująco:&lt;br /&gt;
:&amp;lt;tt&amp;gt;n=np.arange(0,len(t),1)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
zatem kod rekonstruujący może być np. taki:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
n=np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
&lt;br /&gt;
def f1(dt):&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co dt	'''&lt;br /&gt;
	t = np.arange(0,2,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*t)+np.sin(2*np.pi*3*t+np.pi/5)#np.abs(t)#&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
dt = 0.1	&lt;br /&gt;
Fs = 1.0/dt&lt;br /&gt;
&lt;br /&gt;
(s1,t) = sin(f=1,T=2.5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2,t) = sin(f=3,T=2.5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s = s1 + s2&lt;br /&gt;
S = FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
N = len(t)&lt;br /&gt;
&lt;br /&gt;
s_ifft = FFT.ifft(S)&lt;br /&gt;
&lt;br /&gt;
n = np.arange(0,len(t),1)&lt;br /&gt;
s_rekonstrukcja = np.zeros(len(t))&lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
&lt;br /&gt;
py.figure(1)&lt;br /&gt;
py.plot(t,s_ifft,'bo',markersize = 3 )&lt;br /&gt;
py.plot(t,(s_rekonstrukcja),'gx',markersize = 8)&lt;br /&gt;
py.plot(t,s,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Rekonstrukcja na dłuższym odcinku czasu:=====&lt;br /&gt;
Korzystając z wyników poprzedniego polecenia proszę porównać wykres funkcji zadanych wzorami dla odcinak czasu o długości 5s i rekonstrukcję sygnału o długości 5s otrzymanego ze współczynników Fouriera obliczonych dla 2,5s  odcinak czasu.&lt;br /&gt;
* Na jakim odcinku czasu sygnały są zgodne?&lt;br /&gt;
* Co dzieje się na dalszym odcinku czasu?&lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
dalszy ciąg poprzedniego kodu:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.figure(2)&lt;br /&gt;
(s1_d,t_d) = sin(f=1,T=5, Fs= 10, phi =0) #generuję sygnał&lt;br /&gt;
(s2_d,t_d) = sin(f=3,T=5, Fs= 10, phi =np.pi/5)&lt;br /&gt;
s_d = s1_d + s2_d&lt;br /&gt;
&lt;br /&gt;
# rekonstrukcja bazująca na współczynnikach otzrzynmanych dla 2sek fragmentu sygnału&lt;br /&gt;
n=np.arange(0,len(t_d),1)&lt;br /&gt;
s_rekonstrukcja_dluga = np.zeros(len(t_d)) &lt;br /&gt;
for k in range(0,N):&lt;br /&gt;
	s_rekonstrukcja_dluga += 1.0/N * S[k]*np.exp((2j*np.pi*n*k)/N)&lt;br /&gt;
py.plot(t_d,(s_rekonstrukcja_dluga),'gx-',markersize = 8)&lt;br /&gt;
py.plot(t_d,s_d,'r+-',markersize = 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=====Przykład:=====&lt;br /&gt;
Oblicz współczynniki numerycznie korzystając z &amp;lt;tt&amp;gt;numpy.fft.fft&amp;lt;/tt&amp;gt;, porównaj z otrzymanymi analitycznie. Zrób wykresy funkcji i wartości bezwzględnej transformaty. Dla funkcji ''f'' z poprzedniego przykładu danej wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt; f(t)=|t| &amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-1, 1]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1,&lt;br /&gt;
&lt;br /&gt;
Obliczamy współczynniki i robimy wykres:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def f1():&lt;br /&gt;
	'''funkcja zwracająca sygnał moduł t na odcinku -1 1 próbkowanym co 0.1	'''&lt;br /&gt;
	dt = 0.1	&lt;br /&gt;
	t = np.arange(-1,1,dt)&lt;br /&gt;
	s = np.abs(t)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
# część testująca&lt;br /&gt;
Fs = 10.0&lt;br /&gt;
(s,t) = f1() #generuję sygnał&lt;br /&gt;
py.subplot(2,1,1)&lt;br /&gt;
py.stem(t,s)&lt;br /&gt;
&lt;br /&gt;
S=FFT.fft(s) # obliczam transformatę sygnału s&lt;br /&gt;
F = FFT.fftfreq(len(S),Fs) # obliczam skalę częstości &lt;br /&gt;
py.subplot(2,1,2)&lt;br /&gt;
py.stem(F,np.abs(S)/len(s)) # wykreślam widmo amplitudowe&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Porównujemy wyniki z wynikami analitycznymi:&lt;br /&gt;
* &amp;lt;math&amp;gt; f(t) = |cos(t)|&amp;lt;/math&amp;gt; określonej na odcinku &amp;lt;math&amp;gt;t \in [-\pi, \pi]&amp;lt;/math&amp;gt; próbkowanej z interwałem 0.1&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Efekt nieciągłości funkcji ====&lt;br /&gt;
* Wygenerować sinusoidę o następujących własnościach: f=10 Hz, T=1, Fs=100 Hz, i fazie = 1;&lt;br /&gt;
* Przy pomocy subplotów proszę sporządzić rysunek zgodnie z ponższym opisem:&lt;br /&gt;
** subplot(2,2,1): przebieg sygnału w czasie &lt;br /&gt;
** subplot(2,2,2): moduł jego transformaty Fouriera (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(len(s), 1/Fs)&amp;lt;/tt&amp;gt; gdzie &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; to nasz sygnał),&lt;br /&gt;
** subplot(2,2,3): Proszę wykreślić trzykrotnie periodycznie powielony oryginalny sygnał. Można go skonstruować wywołując funkcję: &amp;lt;tt&amp;gt;s_period = np.concatenate((s,s,s))&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** subplot(2,2,4): moduł transformaty Fouriera &amp;lt;tt&amp;gt;s_period&amp;lt;/tt&amp;gt; (narysować za pomocą funkcji &amp;lt;tt&amp;gt;py.stem&amp;lt;/tt&amp;gt;, skalę na osi częstości można uzyskać wywołując funkcję &amp;lt;tt&amp;gt;F = FFT.fftfreq(3*len(s), 1/Fs)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Powtórz te same kroki dla sinusa o częstości 10.3 Hz.&lt;br /&gt;
Pytania:&lt;br /&gt;
# Czym różnią się przedłużenia sinusoidy 10Hz od sinusoidy 10.3Hz? Proszę zwrócić uwagę na miejsca sklejania sygnałów.Porównaj z wynikami otrzymanymi w zagadnieniu '''Rekonstrukcja na dłuższym odcinku czasu'''.&lt;br /&gt;
# Skąd bierze się widoczna różnica w widmie sinusoidy 10Hz i 10.3Hz? &lt;br /&gt;
 *&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s,t) = sin(f = 10.3, T =1, Fs = 100, phi = 1)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s))&lt;br /&gt;
t_period = np.arange(0,3,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Długość sygnału a rozdzielczość widma FFT ====&lt;br /&gt;
Z dotychczasowych rozważań o transformacie Fouriera ograniczonych w czasie sygnałów dyskretnych wynika, że w widmie reprezentowane są częstości od &amp;lt;math&amp;gt;-F_N&amp;lt;/math&amp;gt; do &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;F_N&amp;lt;/math&amp;gt; to częstości Nyquista. Dostępnych binów częstości jest ''N'' - tyle samo ile obserwowanych punktów sygnału. Zatem zwiększenie długości sygnału w czasie poprawia &amp;quot;rozdzielczość&amp;quot;  reprezentacji częstotliwościowej sygnału. &lt;br /&gt;
&lt;br /&gt;
Załóżmy, że dysponujemy jedynie sekwencją ''N'' próbek pewnego sygnału. Rozważymy teraz jakie można przyjąć strategie przedłużania tego sygnału w celu zwiększenia gęstości binów częstotliwościowych i jakie te strategie mają konsekwencje.&lt;br /&gt;
&lt;br /&gt;
=====Przedłużenie przez periodyczną replikację =====&lt;br /&gt;
Rozważając poprzednie przykłady zauważyliśmy, że FFT &amp;quot;widzi&amp;quot; sygnał tak jakby to była nieskończona periodyczna replikacja fragmentu sygnału podanego na wejście. Zatem najbardziej naturalną formą przedłużenia sygnału może wydawać się postępowanie zgodnie z tym sposobem widzenia i dołożenie do sygnału kolejnych segmentów zawierających kopie analizowanego fragmentu sygnału. Zbadajmy empirycznie efekty takiego podejścia. &lt;br /&gt;
&lt;br /&gt;
* Proszę wytworzyć i wykreślić sinusoidy o częstościach 15 i 20 Hz, trwające 0.1s i próbkowane 100Hz. &lt;br /&gt;
** Ile próbek sygnału dostajemy?&lt;br /&gt;
** Proszę obliczyć transformatę Fouriera. Ile punktów w widmie amplitudowym otrzymujemy? Dla jakich cżęstości mamy biny?&lt;br /&gt;
** Proszę skonstruować sygnał będący złożeniem 10 kopii oryginalnego sygnału. &lt;br /&gt;
Jest to 10-krotnie dłuższy fragment sygnału, którego wersję nieskończoną opisują współczynniki obliczone przez transformatę Fouriera. Transformata policzona z takiego wydłużonego odcinak ma 10-krotnie więcej binów. W szczególności zawiera on bin 15Hz. Proszę porównać wykresy widma amplitudowego otrzymanego dla wersji krótkiej i przedłużonej sygnału. Czy wynik jest zaskakujący? Jak go można zrozumieć?&lt;br /&gt;
 * Sygnał przedłużony periodycznie nie zawiera żadnej dodatkowej informacji względem pojedynczego okresu!&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,s,s,s,s,s,s,s,s,s))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S_period))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Przedłużanie sygnału zerami =====&lt;br /&gt;
Inną popularną metodą na zwiększanie ilości binów w transformacie Fouriera jest przedłużanie sygnału zerami (zero-padding). Jest to szczególny przypadek następującego podejścia: Nasz &amp;quot;prawdziwy&amp;quot; sygnał jest długi. Oglądamy go przez prostokątne okno, które ma wartość 1 na odcinku czasu dla którego próbki mamy dostępne i 0 dla pozostałego czasu (więcej o różnych oknach będzie na kolejnych zajęciach). W efekcie możemy myśleć, że oglądany przez nas sygnał to efekt przemnożenia &amp;quot;prawdziwego&amp;quot; sygnału przez okno. Efekty takiego przedłużania proszę zbadać przy użyciu poniższego kodu. &lt;br /&gt;
* Jak można zinterpretować wyniki tego eksperymentu w świetle [[Twierdzenia_o_splocie_i_o_próbkowaniu_(aliasing)#Twierdzenie_o_splocie|twierdzenia o splocie]]?&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
import numpy.fft as FFT&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
 &lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)	&lt;br /&gt;
	&lt;br /&gt;
(s1,t) = sin(f = 15.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
(s2,t)= sin(f = 20.0, T =0.1, Fs = 100, phi = 0)&lt;br /&gt;
s=s1+s2&lt;br /&gt;
py.clf()&lt;br /&gt;
py.subplot(2,2,1)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.subplot(2,2,2)&lt;br /&gt;
S = FFT.fft(s)&lt;br /&gt;
F = FFT.fftfreq(len(s),0.01)&lt;br /&gt;
py.stem(F,np.abs(S)/len(S))&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
z= np.zeros(len(s))&lt;br /&gt;
py.subplot(2,2,3)&lt;br /&gt;
s_period = np.concatenate((s,z,z,z,z,z,z,z,z,z))&lt;br /&gt;
t_period = np.arange(0,len(s_period)/100.0,0.01)&lt;br /&gt;
py.plot(t_period,s_period)&lt;br /&gt;
&lt;br /&gt;
py.subplot(2,2,4)&lt;br /&gt;
S_period = FFT.fft(s_period)&lt;br /&gt;
F_period = FFT.fftfreq(len(s_period),0.01)&lt;br /&gt;
py.stem(F_period,np.abs(S_period)/len(S))&lt;br /&gt;
py.stem(F,np.abs(S)/len(S),linefmt='r-', markerfmt='ro')&lt;br /&gt;
py.xlim((-50,50))&lt;br /&gt;
py.ylim((0,0.7))&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2&amp;diff=4140</id>
		<title>Ćwiczenia 2</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2&amp;diff=4140"/>
		<updated>2015-09-30T12:15:12Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Zadanie */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Transformata Fouriera==&lt;br /&gt;
=== Szereg Fouriera ===&lt;br /&gt;
Ciągłą funkcję  okresową (sygnał okresowy) można przedstawić w postaci  [[Szereg_Fouriera|szeregu Fouriera]] &amp;amp;mdash; czyli sumy zespolonych funkcji exponencjalnych. Współczynniki w szeregu Fouriera to liczby, w ogólności zespolone, które mówią z jaką amplitudą i z jaką fazą wchodzi odpowiadająca mu  funkcja, współczynniki te numerowane są od &amp;lt;math&amp;gt;-\infty&amp;lt;/math&amp;gt; do &amp;lt;math&amp;gt;\infty&amp;lt;/math&amp;gt;. Dla sygnałów rzeczywistych współczynniki występują parami co powoduje, że zgodnie ze wzorami Eulera:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
e^{ix}=\cos x + i\sin x \quad \Rightarrow \begin{cases}\cos x = \frac12(e^{ix}+e^{-ix})\\ \sin x = \frac{1}{2i}(e^{ix}-e^{-ix}) \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
szereg można zwinąć do szeregu funkcji sinusoidalnych.&lt;br /&gt;
&lt;br /&gt;
=== Zadanie ===&lt;br /&gt;
Proszę narysować wykres funkcji &amp;lt;math&amp;gt;f(t) = c \left(e^{i2 \pi \frac{  n  }{T}t } + e^{-i 2 \pi \frac{ n }{T} t  }\right) &amp;lt;/math&amp;gt; dla &amp;lt;math&amp;gt;t \in (-\pi,\, \pi); \quad T = 2 \pi&amp;lt;/math&amp;gt;. &lt;br /&gt;
* Obejrzeć wykresy dla &amp;lt;math&amp;gt;n \in \{0, 1, 2, 5\}&amp;lt;/math&amp;gt;. &lt;br /&gt;
* Jaki sens ma liczba &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;? &lt;br /&gt;
* Jaki sens ma liczba &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;?&lt;br /&gt;
&lt;br /&gt;
===  Obliczanie transformaty ===&lt;br /&gt;
====Przykład ====&lt;br /&gt;
'''Oblicz analitycznie''',  [[Szereg_Fouriera|korzystając ze wzorów]] współczynniki Fouriera dla funkcji ''f''. Za pomocą wykresu coraz to większej ilości składników otrzymanego szeregu sprawdź zbieżność szeregu. &lt;br /&gt;
Funkcja  o okresie 2, w podstawowym okresie dana jest ona wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt; f(t)=|t| &amp;lt;/math&amp;gt; dla &amp;lt;math&amp;gt;|t|&amp;lt;1  &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
Musimy obliczyć następującą całkę:&lt;br /&gt;
:&amp;lt;math&amp;gt; c_n = \frac{1}{2} \int_{-1}^1 {|t| e^{\frac{2 \pi j n t }{2}} dt} = &lt;br /&gt;
\frac{1}{2} \left[ \int_{-1}^0{ -t e^{\pi j n t }dt} + \int_{0}^1 {t e^{\pi j n t }dt} \right]&amp;lt;/math&amp;gt;&lt;br /&gt;
Przypomnijmy sobie, że [http://www.wolframalpha.com/index.html np. korzystając ze strony WolframAlpha]:&lt;br /&gt;
:&amp;lt;math&amp;gt;\int x e^{ax}dx = \frac{1}{a^2} e^{ax} (ax-1) &amp;lt;/math&amp;gt;&lt;br /&gt;
Zatem nasze &amp;lt;math&amp;gt;c_n&amp;lt;/math&amp;gt;:&lt;br /&gt;
: &amp;lt;math&amp;gt;c_n = \frac{1}{\pi^2 n^2} &lt;br /&gt;
\left[ &lt;br /&gt;
- \left[ e^{\pi j n t} \frac{\pi j n t -1}{(\pi j n)^2} \right]_{-1}^0 &lt;br /&gt;
+&lt;br /&gt;
   \left[ e^{\pi j n t} \frac{\pi j n t -1 }{(\pi j n)^2}   \right]_{0}^1&lt;br /&gt;
\right] = &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; = \frac{1}{2 \pi^2 n^2} &lt;br /&gt;
\left[ -2+ \pi j n \left( e^{-\pi j n} - e^{\pi j n} \right) + \left( e^{-\pi j n} + e^{\pi j n} \right)&lt;br /&gt;
\right]&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Korzystając ze wzorów Eulera możemy zwinąć to wyrażenie do funkcji trygonometrycznych:&lt;br /&gt;
:&amp;lt;math&amp;gt;c_n =  \frac{1}{ \pi^2 n^2} (\cos(\pi n ) - \sin(\pi n)  -1)&amp;lt;/math&amp;gt;&lt;br /&gt;
'''Rekonstrukcja sygnałów: '''&lt;br /&gt;
Na podstawie wyników poprzedniego zadania proszę napisać program, który demonstruje jaki jest wynik składania coraz większej ilości czynników.&lt;br /&gt;
Poniższy kod implementuje sumowanie zadanej ilości składników szeregu i ilustruje wynik.&lt;br /&gt;
Proszę uruchomić go dla &amp;lt;tt&amp;gt;N={2, 4, 6, 20}&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W implementacji musimy zwrócić uwagę na fakt, że &amp;lt;math&amp;gt;\lim_{n \rightarrow 0} \frac{1}{ \pi^2 n^2} \left(\cos(\pi n )-\sin(\pi n)  -1\right) = \frac{1}{2}  &amp;lt;/math&amp;gt;&lt;br /&gt;
zaś dla pozostałych ''n'' całkowitych możemy uwzględnić, że &amp;lt;math&amp;gt; \sin(\pi n) = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
def skladnik_modul_t(n ):&lt;br /&gt;
	'''n - który element szeregu'''&lt;br /&gt;
	if n==0:&lt;br /&gt;
		c_n = 0.5&lt;br /&gt;
	else:&lt;br /&gt;
		c_n = 1/(np.pi**2 * n**2) * (-1  + np.cos(np.pi*n) )&lt;br /&gt;
	return c_n&lt;br /&gt;
	&lt;br /&gt;
t = np.arange(-4,4,0.1)&lt;br /&gt;
f = np.zeros(len(t))&lt;br /&gt;
&lt;br /&gt;
N = 10&lt;br /&gt;
c = []&lt;br /&gt;
for n in range(-N,N+1):&lt;br /&gt;
	cn = skladnik_modul_t(n)&lt;br /&gt;
	c.append(cn)&lt;br /&gt;
	f += cn * np.exp(-1j*2*np.pi*t*n/2.0)&lt;br /&gt;
py.plot(t,f)&lt;br /&gt;
for n in range(-N,N+1):&lt;br /&gt;
	print '%(c).4f'%{'c':c[n+N]}&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Zadanie ====&lt;br /&gt;
Analogicznie do powyższego przykładu proszę znaleźć i zbadać szereg Fouriera dla funkcji:&lt;br /&gt;
: &amp;lt;math&amp;gt; f(t) = |cos(t)|&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dyskretna Transformata Fouriera (DFT) ===&lt;br /&gt;
&lt;br /&gt;
W praktycznych zastosowaniach mamy do czynienia z sygnałami próbkowanymi o skończonej długości. Transformata Fouriera działąjąca na takich sygnałach nazywana jest Dyskretną Transformatą Fouriera, a algorytm najczęściej wykorzystywany do jej obliczania to szybka trasnsformata Fouriera (fast Fourier transform FFT). &lt;br /&gt;
Formułę na współczynniki FFT można otrzymać z [[Szereg_Fouriera|szeregu Fouriera]]. Załóżmy, że sygnał który chcemy przetransformować składa się z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; próbek.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; s =\{ s[0],\dots,s[n],\dots s[N-1]\}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
i próbki pobierane były co &amp;lt;math&amp;gt;T_s&amp;lt;/math&amp;gt; sekund. Zakładamy, że analizowany sygnał &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;  to jeden okres nieskończonego sygnału o  okresie  &amp;lt;math&amp;gt;T=N\cdot T_s&amp;lt;/math&amp;gt;. Wprowadźmy oznaczenie: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s[n]=s(nT_s)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Przepiszmy wzór na współczynniki szeregu Fouriera. Ponieważ sygnał jest teraz dyskretny, całka zamieni się na sumę Riemanna: pole będzie sumą pól prostokątów o bokach równych wartości funkcji podcałkowej w zadanych punktach &amp;lt;math&amp;gt;x(nT_s)exp(2i{\pi}knT_s/T)&amp;lt;/math&amp;gt; i odległości między punktami &amp;lt;math&amp;gt;T_s&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
 S[k] = \frac{1}{NT_s}\sum_{n=0}^{N-1}s(nT_s)e^{2i\pi\frac{knT_s}{NT_s}}T_s = \frac{1}{N}\sum_{n=0}^{N-1}s[n]e^{2i{\pi}\frac{kn}{N}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
DFT zaimplementowana w &amp;lt;tt&amp;gt;numpy.fft&amp;lt;/tt&amp;gt; jest określona jako:&lt;br /&gt;
:&amp;lt;math&amp;gt;A[k] =  \sum_{m=0}^{n-1} a[m] \exp\left\{-2\pi i{mk \over n}\right\}       \qquad k = 0,\ldots,n-1.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
DFT jest w ogólności zdefiniowane dla zespolonych argumentów i zwraca zespolone współczynniki. &lt;br /&gt;
Odwrotna dyskretna transformata Fouriera jest zdefiniowana jako:&lt;br /&gt;
:&amp;lt;math&amp;gt; a[m] = \frac{1}{n}\sum_{k=0}^{n-1}A[k]\exp\left\{2\pi i{mk\over n}\right\}&lt;br /&gt;
       \qquad m = 0,\ldots,n-1.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwróćmy uwagę, że różni się ona do transformaty ''wprost'' jedynie znakiem w exponencie i normalizacją &amp;lt;math&amp;gt;1/n&amp;lt;/math&amp;gt;.&lt;br /&gt;
    &lt;br /&gt;
Wartości zwracane przez &amp;lt;tt&amp;gt;fft(a,n)&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; sygnał, &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; ilość punktów transformaty) mają następujący ''standardowy'' porządek:    &lt;br /&gt;
Jeśli &amp;lt;tt&amp;gt;A = fft(a, n)&amp;lt;/tt&amp;gt;, to &lt;br /&gt;
* &amp;lt;tt&amp;gt;A[0]&amp;lt;/tt&amp;gt; zawiera składową stałą (średnią sygnału)&lt;br /&gt;
* &amp;lt;tt&amp;gt;A[1:n/2]&amp;lt;/tt&amp;gt; zawiera współczynniki odpowiadające dodatnim częstościom&lt;br /&gt;
* &amp;lt;tt&amp;gt;A[n/2+1:]&amp;lt;/tt&amp;gt; zawiera współczynniki odpowiadające ujemnym częstościom w kolejności od bardziej do mniej ujemnych.&lt;br /&gt;
* Dla parzystego ''n''  &amp;lt;tt&amp;gt;A[n/2]&amp;lt;/tt&amp;gt; reprezentuje dodatnia i ujemną częstość Nyquista i dla sygnałów rzeczywistych jest liczbą rzeczywistą. &lt;br /&gt;
* Dla nieparzystego &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;, element &amp;lt;tt&amp;gt;A[(n-1)/2]&amp;lt;/tt&amp;gt; zawiera współczynnik dla największej częstości dodatniej a element &amp;lt;tt&amp;gt;A[(n+1)/2]&amp;lt;/tt&amp;gt; zawiera współczynnik dla największej częstości ujemnej.&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;numpy.fft.fftfreq(len(A),1.0/Fs)&amp;lt;/tt&amp;gt; zwraca macierz częstości odpowiadających poszczególnym elementom wyjściowym.&lt;br /&gt;
&lt;br /&gt;
Składnia:  &amp;lt;tt&amp;gt;numpy.fft.fftfreq(n, d=1.0)&amp;lt;/tt&amp;gt;&lt;br /&gt;
Parametry:&lt;br /&gt;
:&amp;lt;tt&amp;gt;n : int&amp;lt;/tt&amp;gt; &amp;amp;mdash; długość okna.&lt;br /&gt;
:&amp;lt;tt&amp;gt;d : skalar&amp;lt;/tt&amp;gt; &amp;amp;mdash; okres próbkowania (odwrotność częstości próbkowania).&lt;br /&gt;
:Zwracane częstości są obliczane w następujący sposób:&lt;br /&gt;
:&amp;lt;tt&amp;gt;f = [0,1,...,n/2-1,-n/2,...,-1]/(d*n)&amp;lt;/tt&amp;gt;         jeśli &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; jest przyste&lt;br /&gt;
:&amp;lt;tt&amp;gt;f = [0,1,...,(n-1)/2,-(n-1)/2,...,-1]/(d*n) &amp;lt;/tt&amp;gt;  jeśli  &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; jest nieparzyste. &lt;br /&gt;
    &lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;numpy.fft.fftshift(A)&amp;lt;/tt&amp;gt; przestawia wektor wyjściowy &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt; i wektor częstości, tak aby częstość zero wypadała w środku. Zastosowanie funkcji &amp;lt;tt&amp;gt;numpy.fft.ifftshift(A)&amp;lt;/tt&amp;gt; odwraca działanie &amp;lt;tt&amp;gt;numpy.fft.fftshift(.)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
    &lt;br /&gt;
Jeśli potraktujemy wejście &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jako sygnał w dziedzinie czasu i policzymy &amp;lt;tt&amp;gt;A = fft(a)&amp;lt;/tt&amp;gt;, wówczas &amp;lt;tt&amp;gt;np.abs(A)&amp;lt;/tt&amp;gt; jest widmem amplitudowym, zaś &amp;lt;tt&amp;gt;np.abs(A)**2&amp;lt;/tt&amp;gt; jest widmem mocy. Można obliczyć także widmo fazowe za pomocą funkcji  &amp;lt;tt&amp;gt;np.angle(A)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Zadanie ====&lt;br /&gt;
&lt;br /&gt;
* Proszę wygenerować cosinusoidę  oraz sinusoidę o długości 1s, częstości 2Hz próbkowaną 10Hz. Proszę obliczyć współczynniki i wypisać je. &lt;br /&gt;
** Jakiego typu liczby otrzymaliśmy?&lt;br /&gt;
** Czy istnieją jakieś związki między współczynnikami?&lt;br /&gt;
** Jaki jest związek między długością wejściowego sygnału i wyjściowych współczynników?&lt;br /&gt;
&lt;br /&gt;
=== Transformaty rzeczywiste i Hermitowskie ===&lt;br /&gt;
Jeśli sygnał wejściowy jest rzeczywisty to jego transformata jest hermitowska, tzn. współczynnik przy częstości &amp;lt;math&amp;gt;f_k&amp;lt;/math&amp;gt; jest sprzężony ze współczynnikiem przy częstości &amp;lt;math&amp;gt;-f_k&amp;lt;/math&amp;gt;. Oznacza to, że dla sygnałów rzeczywistych współczynniki przy ujemnych częstościach nie wnoszą żadnej dodatkowej informacji.  Rodzina funkcji  &amp;lt;tt&amp;gt;rfft&amp;lt;/tt&amp;gt; wykorzystuje tą symetrię i zwracają tylko dodatnią część widma włącznie z częstością Nyquista. Tak więc, &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; punktów rzeczywistych na wejściu daje na wyjściu &amp;lt;math&amp;gt;\frac{n}{2}+1&amp;lt;/math&amp;gt; punktów zespolonych. Funkcje odwrotne w tej rodzinie zakładają tą samą symetrię i aby na wyjściu uzyskać &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;  punktów rzeczywistych na wejściu trzeba podać &amp;lt;math&amp;gt;\frac{n}{2}+1&amp;lt;/math&amp;gt; wartości zespolonych.&lt;br /&gt;
    &lt;br /&gt;
Dla kompletności powiedzmy jeszcze, że możliwy jest przypadek odwrotny, tzn. widmo jest czysto rzeczywiste i odpowiada mu hermitowski sygnał zespolony. Tę symetrię wykorzystują funkcje &amp;lt;tt&amp;gt;hfft&amp;lt;/tt&amp;gt;, które zakładają, że operujemy w dziedzinie czasu &amp;lt;math&amp;gt;\frac{n}{2}+1&amp;lt;/math&amp;gt; punktami zespolonymi i odpowiadającymi im w dziedzinie częstości &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; punktami rzeczywistymi.&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2&amp;diff=4139</id>
		<title>Ćwiczenia 2</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_2&amp;diff=4139"/>
		<updated>2015-09-30T12:09:36Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Dyskretna Transformata Fouriera (DFT) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Transformata Fouriera==&lt;br /&gt;
=== Szereg Fouriera ===&lt;br /&gt;
Ciągłą funkcję  okresową (sygnał okresowy) można przedstawić w postaci  [[Szereg_Fouriera|szeregu Fouriera]] &amp;amp;mdash; czyli sumy zespolonych funkcji exponencjalnych. Współczynniki w szeregu Fouriera to liczby, w ogólności zespolone, które mówią z jaką amplitudą i z jaką fazą wchodzi odpowiadająca mu  funkcja, współczynniki te numerowane są od &amp;lt;math&amp;gt;-\infty&amp;lt;/math&amp;gt; do &amp;lt;math&amp;gt;\infty&amp;lt;/math&amp;gt;. Dla sygnałów rzeczywistych współczynniki występują parami co powoduje, że zgodnie ze wzorami Eulera:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
e^{ix}=\cos x + i\sin x \quad \Rightarrow \begin{cases}\cos x = \frac12(e^{ix}+e^{-ix})\\ \sin x = \frac{1}{2i}(e^{ix}-e^{-ix}) \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
szereg można zwinąć do szeregu funkcji sinusoidalnych.&lt;br /&gt;
&lt;br /&gt;
=== Zadanie ===&lt;br /&gt;
Proszę narysować wykres funkcji &amp;lt;math&amp;gt;f(t) = c \left(e^{i2 \pi \frac{  n  }{T}t } + e^{-i 2 \pi \frac{ n }{T} t  }\right) &amp;lt;/math&amp;gt; dla &amp;lt;math&amp;gt;t \in (-\pi,\, \pi); \quad T = 2 \pi&amp;lt;/math&amp;gt;. &lt;br /&gt;
* Obejrzeć wykresy dla &amp;lt;math&amp;gt;n \in \{0, 1, 2, 5\}&amp;lt;/math&amp;gt;. &lt;br /&gt;
* Jaki sens ma liczba &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;? &lt;br /&gt;
* Jaki sens ma liczba &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;?&lt;br /&gt;
&lt;br /&gt;
===  Obliczanie transformaty ===&lt;br /&gt;
====Przykład ====&lt;br /&gt;
'''Oblicz analitycznie''',  [[Szereg_Fouriera|korzystając ze wzorów]] współczynniki Fouriera dla funkcji ''f''. Za pomocą wykresu coraz to większej ilości składników otrzymanego szeregu sprawdź zbieżność szeregu. &lt;br /&gt;
Funkcja  o okresie 2, w podstawowym okresie dana jest ona wzorem:&lt;br /&gt;
:&amp;lt;math&amp;gt; f(t)=|t| &amp;lt;/math&amp;gt; dla &amp;lt;math&amp;gt;|t|&amp;lt;1  &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
Musimy obliczyć następującą całkę:&lt;br /&gt;
:&amp;lt;math&amp;gt; c_n = \frac{1}{2} \int_{-1}^1 {|t| e^{\frac{2 \pi j n t }{2}} dt} = &lt;br /&gt;
\frac{1}{2} \left[ \int_{-1}^0{ -t e^{\pi j n t }dt} + \int_{0}^1 {t e^{\pi j n t }dt} \right]&amp;lt;/math&amp;gt;&lt;br /&gt;
Przypomnijmy sobie, że [http://www.wolframalpha.com/index.html np. korzystając ze strony WolframAlpha]:&lt;br /&gt;
:&amp;lt;math&amp;gt;\int x e^{ax}dx = \frac{1}{a^2} e^{ax} (ax-1) &amp;lt;/math&amp;gt;&lt;br /&gt;
Zatem nasze &amp;lt;math&amp;gt;c_n&amp;lt;/math&amp;gt;:&lt;br /&gt;
: &amp;lt;math&amp;gt;c_n = \frac{1}{\pi^2 n^2} &lt;br /&gt;
\left[ &lt;br /&gt;
- \left[ e^{\pi j n t} \frac{\pi j n t -1}{(\pi j n)^2} \right]_{-1}^0 &lt;br /&gt;
+&lt;br /&gt;
   \left[ e^{\pi j n t} \frac{\pi j n t -1 }{(\pi j n)^2}   \right]_{0}^1&lt;br /&gt;
\right] = &amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt; = \frac{1}{2 \pi^2 n^2} &lt;br /&gt;
\left[ -2+ \pi j n \left( e^{-\pi j n} - e^{\pi j n} \right) + \left( e^{-\pi j n} + e^{\pi j n} \right)&lt;br /&gt;
\right]&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Korzystając ze wzorów Eulera możemy zwinąć to wyrażenie do funkcji trygonometrycznych:&lt;br /&gt;
:&amp;lt;math&amp;gt;c_n =  \frac{1}{ \pi^2 n^2} (\cos(\pi n ) - \sin(\pi n)  -1)&amp;lt;/math&amp;gt;&lt;br /&gt;
'''Rekonstrukcja sygnałów: '''&lt;br /&gt;
Na podstawie wyników poprzedniego zadania proszę napisać program, który demonstruje jaki jest wynik składania coraz większej ilości czynników.&lt;br /&gt;
Poniższy kod implementuje sumowanie zadanej ilości składników szeregu i ilustruje wynik.&lt;br /&gt;
Proszę uruchomić go dla &amp;lt;tt&amp;gt;N={2, 4, 6, 20}&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W implementacji musimy zwrócić uwagę na fakt, że &amp;lt;math&amp;gt;\lim_{n \rightarrow 0} \frac{1}{ \pi^2 n^2} \left(\cos(\pi n )-\sin(\pi n)  -1\right) = \frac{1}{2}  &amp;lt;/math&amp;gt;&lt;br /&gt;
zaś dla pozostałych ''n'' całkowitych możemy uwzględnić, że &amp;lt;math&amp;gt; \sin(\pi n) = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
def skladnik_modul_t(n ):&lt;br /&gt;
	'''n - który element szeregu'''&lt;br /&gt;
	if n==0:&lt;br /&gt;
		c_n = 0.5&lt;br /&gt;
	else:&lt;br /&gt;
		c_n = 1/(np.pi**2 * n**2) * (-1  + np.cos(np.pi*n) )&lt;br /&gt;
	return c_n&lt;br /&gt;
	&lt;br /&gt;
t = np.arange(-4,4,0.1)&lt;br /&gt;
f = np.zeros(len(t))&lt;br /&gt;
&lt;br /&gt;
N = 10&lt;br /&gt;
c = []&lt;br /&gt;
for n in range(-N,N+1):&lt;br /&gt;
	cn = skladnik_modul_t(n)&lt;br /&gt;
	c.append(cn)&lt;br /&gt;
	f += cn * np.exp(-1j*2*np.pi*t*n/2.0)&lt;br /&gt;
py.plot(t,f)&lt;br /&gt;
for n in range(-N,N+1):&lt;br /&gt;
	print '%(c).4f'%{'c':c[n+N]}&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Zadanie ====&lt;br /&gt;
Analogicznie do powyższego przykładu proszę znaleźć i zbadać szereg Fouriera dla funkcji:&lt;br /&gt;
: &amp;lt;math&amp;gt; f(t) = |cos(t)|&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Dyskretna Transformata Fouriera (DFT) ===&lt;br /&gt;
&lt;br /&gt;
W praktycznych zastosowaniach mamy do czynienia z sygnałami próbkowanymi o skończonej długości. Transformata Fouriera działąjąca na takich sygnałach nazywana jest Dyskretną Transformatą Fouriera, a algorytm najczęściej wykorzystywany do jej obliczania to szybka trasnsformata Fouriera (fast Fourier transform FFT). &lt;br /&gt;
Formułę na współczynniki FFT można otrzymać z [[Szereg_Fouriera|szeregu Fouriera]]. Załóżmy, że sygnał który chcemy przetransformować składa się z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; próbek.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; s =\{ s[0],\dots,s[n],\dots s[N-1]\}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
i próbki pobierane były co &amp;lt;math&amp;gt;T_s&amp;lt;/math&amp;gt; sekund. Zakładamy, że analizowany sygnał &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;  to jeden okres nieskończonego sygnału o  okresie  &amp;lt;math&amp;gt;T=N\cdot T_s&amp;lt;/math&amp;gt;. Wprowadźmy oznaczenie: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s[n]=s(nT_s)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Przepiszmy wzór na współczynniki szeregu Fouriera. Ponieważ sygnał jest teraz dyskretny, całka zamieni się na sumę Riemanna: pole będzie sumą pól prostokątów o bokach równych wartości funkcji podcałkowej w zadanych punktach &amp;lt;math&amp;gt;x(nT_s)exp(2i{\pi}knT_s/T)&amp;lt;/math&amp;gt; i odległości między punktami &amp;lt;math&amp;gt;T_s&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
 S[k] = \frac{1}{NT_s}\sum_{n=0}^{N-1}s(nT_s)e^{2i\pi\frac{knT_s}{NT_s}}T_s = \frac{1}{N}\sum_{n=0}^{N-1}s[n]e^{2i{\pi}\frac{kn}{N}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
DFT zaimplementowana w &amp;lt;tt&amp;gt;numpy.fft&amp;lt;/tt&amp;gt; jest określona jako:&lt;br /&gt;
:&amp;lt;math&amp;gt;A[k] =  \sum_{m=0}^{n-1} a[m] \exp\left\{-2\pi i{mk \over n}\right\}       \qquad k = 0,\ldots,n-1.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
DFT jest w ogólności zdefiniowane dla zespolonych argumentów i zwraca zespolone współczynniki. &lt;br /&gt;
Odwrotna dyskretna transformata Fouriera jest zdefiniowana jako:&lt;br /&gt;
:&amp;lt;math&amp;gt; a[m] = \frac{1}{n}\sum_{k=0}^{n-1}A[k]\exp\left\{2\pi i{mk\over n}\right\}&lt;br /&gt;
       \qquad m = 0,\ldots,n-1.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwróćmy uwagę, że różni się ona do transformaty ''wprost'' jedynie znakiem w exponencie i normalizacją &amp;lt;math&amp;gt;1/n&amp;lt;/math&amp;gt;.&lt;br /&gt;
    &lt;br /&gt;
Wartości zwracane przez &amp;lt;tt&amp;gt;fft(a,n)&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; sygnał, &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; ilość punktów transformaty) mają następujący ''standardowy'' porządek:    &lt;br /&gt;
Jeśli &amp;lt;tt&amp;gt;A = fft(a, n)&amp;lt;/tt&amp;gt;, to &lt;br /&gt;
* &amp;lt;tt&amp;gt;A[0]&amp;lt;/tt&amp;gt; zawiera składową stałą (średnią sygnału)&lt;br /&gt;
* &amp;lt;tt&amp;gt;A[1:n/2]&amp;lt;/tt&amp;gt; zawiera współczynniki odpowiadające dodatnim częstościom&lt;br /&gt;
* &amp;lt;tt&amp;gt;A[n/2+1:]&amp;lt;/tt&amp;gt; zawiera współczynniki odpowiadające ujemnym częstościom w kolejności od bardziej do mniej ujemnych.&lt;br /&gt;
* Dla parzystego ''n''  &amp;lt;tt&amp;gt;A[n/2]&amp;lt;/tt&amp;gt; reprezentuje dodatnia i ujemną częstość Nyquista i dla sygnałów rzeczywistych jest liczbą rzeczywistą. &lt;br /&gt;
* Dla nieparzystego &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;, element &amp;lt;tt&amp;gt;A[(n-1)/2]&amp;lt;/tt&amp;gt; zawiera współczynnik dla największej częstości dodatniej a element &amp;lt;tt&amp;gt;A[(n+1)/2]&amp;lt;/tt&amp;gt; zawiera współczynnik dla największej częstości ujemnej.&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;numpy.fft.fftfreq(len(A),1.0/Fs)&amp;lt;/tt&amp;gt; zwraca macierz częstości odpowiadających poszczególnym elementom wyjściowym.&lt;br /&gt;
&lt;br /&gt;
Składnia:  &amp;lt;tt&amp;gt;numpy.fft.fftfreq(n, d=1.0)&amp;lt;/tt&amp;gt;&lt;br /&gt;
Parametry:&lt;br /&gt;
:&amp;lt;tt&amp;gt;n : int&amp;lt;/tt&amp;gt; &amp;amp;mdash; długość okna.&lt;br /&gt;
:&amp;lt;tt&amp;gt;d : skalar&amp;lt;/tt&amp;gt; &amp;amp;mdash; okres próbkowania (odwrotność częstości próbkowania).&lt;br /&gt;
:Zwracane częstości są obliczane w następujący sposób:&lt;br /&gt;
:&amp;lt;tt&amp;gt;f = [0,1,...,n/2-1,-n/2,...,-1]/(d*n)&amp;lt;/tt&amp;gt;         jeśli &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; jest przyste&lt;br /&gt;
:&amp;lt;tt&amp;gt;f = [0,1,...,(n-1)/2,-(n-1)/2,...,-1]/(d*n) &amp;lt;/tt&amp;gt;  jeśli  &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; jest nieparzyste. &lt;br /&gt;
    &lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;numpy.fft.fftshift(A)&amp;lt;/tt&amp;gt; przestawia wektor wyjściowy &amp;lt;tt&amp;gt;fft&amp;lt;/tt&amp;gt; i wektor częstości, tak aby częstość zero wypadała w środku. Zastosowanie funkcji &amp;lt;tt&amp;gt;numpy.fft.ifftshift(A)&amp;lt;/tt&amp;gt; odwraca działanie &amp;lt;tt&amp;gt;numpy.fft.fftshift(.)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
    &lt;br /&gt;
Jeśli potraktujemy wejście &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jako sygnał w dziedzinie czasu i policzymy &amp;lt;tt&amp;gt;A = fft(a)&amp;lt;/tt&amp;gt;, wówczas &amp;lt;tt&amp;gt;np.abs(A)&amp;lt;/tt&amp;gt; jest widmem amplitudowym, zaś &amp;lt;tt&amp;gt;np.abs(A)**2&amp;lt;/tt&amp;gt; jest widmem mocy. Można obliczyć także widmo fazowe za pomocą funkcji  &amp;lt;tt&amp;gt;np.angle(A)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Zadanie ====&lt;br /&gt;
&lt;br /&gt;
=== Transformaty rzeczywiste i Hermitowskie ===&lt;br /&gt;
Jeśli sygnał wejściowy jest rzeczywisty to jego transformata jest hermitowska, tzn. współczynnik przy częstości &amp;lt;math&amp;gt;f_k&amp;lt;/math&amp;gt; jest sprzężony ze współczynnikiem przy częstości &amp;lt;math&amp;gt;-f_k&amp;lt;/math&amp;gt;. Oznacza to, że dla sygnałów rzeczywistych współczynniki przy ujemnych częstościach nie wnoszą żadnej dodatkowej informacji.  Rodzina funkcji  &amp;lt;tt&amp;gt;rfft&amp;lt;/tt&amp;gt; wykorzystuje tą symetrię i zwracają tylko dodatnią część widma włącznie z częstością Nyquista. Tak więc, &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; punktów rzeczywistych na wejściu daje na wyjściu &amp;lt;math&amp;gt;\frac{n}{2}+1&amp;lt;/math&amp;gt; punktów zespolonych. Funkcje odwrotne w tej rodzinie zakładają tą samą symetrię i aby na wyjściu uzyskać &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;  punktów rzeczywistych na wejściu trzeba podać &amp;lt;math&amp;gt;\frac{n}{2}+1&amp;lt;/math&amp;gt; wartości zespolonych.&lt;br /&gt;
    &lt;br /&gt;
Dla kompletności powiedzmy jeszcze, że możliwy jest przypadek odwrotny, tzn. widmo jest czysto rzeczywiste i odpowiada mu hermitowski sygnał zespolony. Tę symetrię wykorzystują funkcje &amp;lt;tt&amp;gt;hfft&amp;lt;/tt&amp;gt;, które zakładają, że operujemy w dziedzinie czasu &amp;lt;math&amp;gt;\frac{n}{2}+1&amp;lt;/math&amp;gt; punktami zespolonymi i odpowiadającymi im w dziedzinie częstości &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; punktami rzeczywistymi.&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_1&amp;diff=4138</id>
		<title>Ćwiczenia 1</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%C4%86wiczenia_1&amp;diff=4138"/>
		<updated>2015-09-30T11:57:58Z</updated>

		<summary type="html">&lt;p&gt;Magdaz: /* Przykład: eksport sygnału do pliku binarnego */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dokumentacja modułu scipy.signal ==&lt;br /&gt;
Proszę zapoznać się z dokumentacją biblioteki scipy.signal:&lt;br /&gt;
&lt;br /&gt;
http://docs.scipy.org/doc/scipy-0.14.0/reference/signal.html&lt;br /&gt;
&lt;br /&gt;
==Sygnały ciągłe i dyskretne ==&lt;br /&gt;
===Próbkowanie w czasie ===&lt;br /&gt;
Proszę powtórzyć sobie pojęcia:&lt;br /&gt;
* częstość próbkowania&lt;br /&gt;
* częstość Nyquista&lt;br /&gt;
* aliasing&lt;br /&gt;
&lt;br /&gt;
W poniższym ćwiczeniu chcemy zbadać efekt próbkowania sygnału w czasie. W komputerach nie mamy dostępu do sygnału ciągłego. Na nasze potrzeby wygenerujemy sygnały próbkowane z bardzo dużą częstością, które będą dla nas aproksymacją sygnałów ciągłych. Przy ich pomocy zaprezentujemy efekt utożsamiania (aliasingu).&lt;br /&gt;
&lt;br /&gt;
Proszę wytworzyć wektor reprezentujący czas &amp;amp;bdquo;prawie&amp;amp;rdquo; ciągły. Będzie to u nas 1000 wartości z przedziału [0,1) wziętych z odstępem 0,001.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
t = np.arange(0,1,0.001) # czas 'prawie ciągły'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Teraz proszę wygenerować dwie sinusoidy: jedną o częstości &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; a drugą o częstości &amp;lt;tt&amp;gt;9&amp;lt;/tt&amp;gt;. Dla przypomnienia wyrażenie:&lt;br /&gt;
:&amp;lt;math&amp;gt; s(t) = \sin(2 \pi f t)&amp;lt;/math&amp;gt; możemy w pythonie zapisać:&lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
s = np.sin(2*np.pi*f*t)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Proszę [[TI/Matplotlib#Kilka_wykres.C3.B3w_we_wsp.C3.B3lnych_osiach|wykreślić]] obie sinusoidy.&lt;br /&gt;
&lt;br /&gt;
Teraz proszę spróbkować czas i nasze &amp;amp;bdquo;prawie&amp;amp;rdquo; ciągłe sinusoidy z okresem próbkowania 0,1. (Trzeba pobrać co 100 element, proszę posłużyć się [[Programowanie_z_Pythonem/Sekwencje#Wycinki|wycinkami]]) &amp;lt;!-- [[TI/Sekwencje|Struktury danych — sekwencje|wycinkami]]. --&amp;gt;&lt;br /&gt;
Na tle &amp;amp;bdquo;prawie&amp;amp;rdquo; ciągłych sinusoid proszę dorysować punkty ze spróbkowanych sygnałów. Aby punkty były dobrze  widoczne proponuję użyć markerów &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; oraz &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Proszę zaobserwować wzajemne położenie punktów. Czy można odróżnić sinusoidę o częstości &amp;amp;minus;1 od sinusoidy o częstości 9, jeśli obie są próbkowane z częstością 10? Jak można uogólnić tą obserwację?&lt;br /&gt;
  &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
t = np.arange(0,1,0.001) # czas 'prawie ciągły'&lt;br /&gt;
f1 = -1 # częstość sygnału 1&lt;br /&gt;
f2 = 9 # częstość sygnału 2&lt;br /&gt;
s1 = np.sin(2*np.pi*f1*t) # prawie ciągły sygnał o częstości f1&lt;br /&gt;
s2 = np.sin(2*np.pi*f2*t) # prawie ciągły sygnał o częstości f2&lt;br /&gt;
&lt;br /&gt;
T = 0.1 # okres próbkowania&lt;br /&gt;
Fs = 1/T # częstość próbkowania&lt;br /&gt;
FN = Fs/2 # częstość Nyquista&lt;br /&gt;
T_samp = t[0::100] # czas pobierania próbek&lt;br /&gt;
s1_samp = s1[0::100] # próbkowany sygnał o częstości f1&lt;br /&gt;
s2_samp = s2[0::100] # próbkowany sygnał o częstości f2&lt;br /&gt;
&lt;br /&gt;
py.plot(t, s1, 'g')&lt;br /&gt;
py.plot(t, s2, 'b')&lt;br /&gt;
py.plot(T_samp, s1_samp, 'gx', markersize=10)&lt;br /&gt;
py.plot(T_samp, s2_samp, 'r+', markersize=10)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===Błąd kwantyzacji ===&lt;br /&gt;
Kiedy mierzymy fizyczne wielkości w celu dalszej analizy najczęściej chcemy przypisać im pewne liczby. Liczby w systemach cyfrowych reprezentowane są ze skończoną dokładnością. Urządzenia dokonujące przypisania liczby do mierzonej wartości to przetworniki analogowo-cyfrowe (ang. ADC, Analog to Digital Converter).&lt;br /&gt;
Charakteryzują się one określoną ilością bitów ''N'', za pomocą których reprezentują liczby. Pełen zakres wartości pomiarowych ''R'' jest dzielony na &amp;lt;math&amp;gt;2^N&amp;lt;/math&amp;gt; poziomów. Błąd kwantyzacji szacujemy jako nie większy niż &amp;lt;math&amp;gt; \frac{R}{2^{N+1}} &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
====Zadanie:====&lt;br /&gt;
Proszę oszacować błąd kwantyzacji sygnału EEG mierzonego za pomocą 12-bitowego konwertera. Zakres pomiarowy tego urządzenia to &amp;amp;plusmn;200 &amp;amp;mu;V.&lt;br /&gt;
====Zadanie:====&lt;br /&gt;
Proszę zilustrować efekt kwantyzacji dla trzybitowego przetwornika o zakresie 2.&lt;br /&gt;
W tym celu proszę wykonać następujące kroki:&lt;br /&gt;
# wygenerować &amp;amp;bdquo;prawie&amp;amp;rdquo; ciągłą sinusoidę (częstość 1, czas trwania 1 próbkowanie co 0,001)&lt;br /&gt;
# spróbkować tą sinusoidę co 0,1 (proszę zastosować wycinki)&lt;br /&gt;
# proszę skwantować spróbkowane wartości &lt;br /&gt;
#Proszę wykreślić na jednym rysunku &lt;br /&gt;
#* oryginalny sygnał &lt;br /&gt;
#* sygnał spróbkowany w czasie&lt;br /&gt;
#* sygnał spróbkowany w czasie i o skwantowanej amplitudzie (skorzystać z funkcji &amp;lt;tt&amp;gt;py.step&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
{{ Wyjaśnienie|title= wskazówka: Kwantowanie | text = &lt;br /&gt;
&amp;lt;source lang =python&amp;gt;&lt;br /&gt;
N_bits = 3&lt;br /&gt;
zakres = 2.0&lt;br /&gt;
dy = zakres/2**N_bits&lt;br /&gt;
s1_kwantowany = np.floor(s1_samp/dy)*dy +0.5*dy&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
t = np.arange(0,1,0.001) # czas 'prawie ciągły'&lt;br /&gt;
f1 = 1 # częstość sygnału 1&lt;br /&gt;
&lt;br /&gt;
s1 = np.sin(2*np.pi*f1*t) # prawie ciągły sygnał o częstości f1&lt;br /&gt;
T_samp = t[0::100]&lt;br /&gt;
s1_samp = s1[0::100]&lt;br /&gt;
&lt;br /&gt;
N_bits = 3&lt;br /&gt;
zakres = 2.0&lt;br /&gt;
dy = zakres/2**N_bits&lt;br /&gt;
s1_kwantowany = np.floor(s1_samp/dy)*dy +0.5*dy&lt;br /&gt;
ax = py.subplot(111)&lt;br /&gt;
py.plot(t,s1)&lt;br /&gt;
py.plot(T_samp,s1_samp,'ko',markersize = 5)&lt;br /&gt;
py.step(T_samp,s1_kwantowany,where = 'post')&lt;br /&gt;
&lt;br /&gt;
ax.set_xticks(T_samp)&lt;br /&gt;
poziomy = np.arange(-1+0.5*dy,1,dy)&lt;br /&gt;
ax.set_yticks(poziomy)&lt;br /&gt;
py.grid('on')&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
for i in xrange(0,8):&lt;br /&gt;
	py.text(1.02,poziomy[i],bin(i))&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Sygnały testowe==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Generowanie sygnałów testowych ===&lt;br /&gt;
&lt;br /&gt;
Do badania różnych metod analizy sygnałów potrzebne nam będą sygnały o znanych własnościach. W szczególności dobrze jest umnieć nadać sygnałom występującym w postaci cyfrowej, oraz sztucznym sygnałom próbnym pewne własności fizyczne takie jak:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	czętość próbkowania&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	czas trwania&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;li&amp;gt;&lt;br /&gt;
	amplituda&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
=== Przykład sinus===&lt;br /&gt;
Sinus o zadanej częstości (w Hz), długości trwania, częstości próbkowania i fazie.&lt;br /&gt;
Poniższy kod implementuje i testuje funkcję &lt;br /&gt;
:&amp;lt;math&amp;gt; \sin(f,T,Fs,\phi) = \sin(2*\pi f t)&amp;lt;/math&amp;gt; dla &amp;lt;math&amp;gt;t \in \{0,T\}&amp;lt;/math&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang= python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import pylab as py&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
def sin(f = 1, T = 1, Fs = 128, phi =0 ):&lt;br /&gt;
	'''sin o zadanej częstości (w Hz), długości, fazie i częstości próbkowania&lt;br /&gt;
	Domyślnie wytwarzany jest sygnał reprezentujący &lt;br /&gt;
	1 sekundę sinusa o częstości 1 Hz i zerowej fazie próbkowanego 128 Hz&lt;br /&gt;
	'''&lt;br /&gt;
&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	s = np.sin(2*np.pi*f*t + phi)&lt;br /&gt;
	return (s,t)&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
(s,t) = sin(f=10,Fs=1000)&lt;br /&gt;
py.plot(t,s)&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
=== Przykład: eksport sygnału do pliku binarnego ===&lt;br /&gt;
* Poniższy kod ilustruje sposób zapisu dwóch funkcji sinus o częstościach 10 Hz i 21 Hz do pliku binarnego:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang= python&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    T = 5&lt;br /&gt;
    Fs = 128.0&lt;br /&gt;
&lt;br /&gt;
    freqs = [10,21] #częstości funkcji sinus	&lt;br /&gt;
    signal = np.zeros((T*Fs, len(freqs)), dtype='&amp;lt;f')&lt;br /&gt;
&lt;br /&gt;
    for i,f in enumerate(freqs):&lt;br /&gt;
        s = sin(f=f, T=T, Fs=Fs)&lt;br /&gt;
        signal[:,i] = s&lt;br /&gt;
&lt;br /&gt;
    with open('test_signal.bin', 'wb') as f:&lt;br /&gt;
        signal.tofile(f)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Przykład: wczytanie sygnału do Svaroga ===&lt;br /&gt;
W celu wczytania zapisanego binarnie sygnału do programu Svarog, po wybraniu File -&amp;gt; Open signal, należy wprowadzić częstość próbkowania sygnału oraz liczbę kanałów. &lt;br /&gt;
&lt;br /&gt;
[[Plik:svarog_open_signal.png|center|800px|thumb|&amp;lt;figure id=&amp;quot;uid3&amp;quot; /&amp;gt;Wczytywanie sygnału w programie Svarog.]]&lt;br /&gt;
&lt;br /&gt;
=== Delta ===&lt;br /&gt;
Podobnie można zdefiniować funkcję delta o zadanym czasie trwania, częstości próbkowania i momencie wystąpienia impulsu:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt; \delta(t_0) = \left\{^{1 \quad t=t_0} _{0 \quad t \ne t_0} \right.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang= python&amp;gt;&lt;br /&gt;
def delta(t0=0.5, T=1  ,Fs = 128):&lt;br /&gt;
	dt = 1.0/Fs&lt;br /&gt;
	t = np.arange(0,T,dt)&lt;br /&gt;
	d = np.zeros(len(t))&lt;br /&gt;
	d[np.ceil(t0*Fs)]=1&lt;br /&gt;
	return (d,t)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Zadanie:===&lt;br /&gt;
Analogicznie do powyższych przykładów proszę zaimplementować iprzetestować funkcje generujące:&lt;br /&gt;
* funkcję Gabora (funkcja Gaussa modulowana cosinusem) o zadanej częstości i standardowym odchyleniu w czasie, momencie wystąpienia, długości, częstości próbkowania i fazie. &lt;br /&gt;
:&amp;lt;math&amp;gt; g = \exp\left(-\frac{1}{2}\left(\frac{t-t_0}{\sigma}\right)^2 \right) \cdot  \cos(2 \pi f t + \phi); &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* szum gaussowski o zadanej średniej, odchyleniu standardowym, długości i częstości próbkowania.&lt;br /&gt;
&lt;br /&gt;
* pochodną funkcji Gaussa&lt;br /&gt;
&lt;br /&gt;
* połówkę funkcji Gaussa&lt;/div&gt;</summary>
		<author><name>Magdaz</name></author>
		
	</entry>
</feed>