Zadanie 1
Zaimportować do MATLABa plik
test_data.csv
.Najprościej będzie użyć aplikacji Import Data; dane zawierają trzy kolumny:
time
,IR
,RED
zebrane z czujnika pulsu korzystającego z diod LED czerwonej i podczerwonej.Narysować wykres danych.
Wybrać jeden z przebiegów (
IR
alboRED
) i wykonać operację usuwania trendudetrend()
(opis funkcji dalej). Wybrać metodę dającą (subiektywnie) najlepszy efekt.Narysować wykres przebiegu oryginalnego i po usunięciu trendu.
Zadanie 2
Zaimportować do MATLABa plik
temperatury.csv
pochodzą one z pomiarów temperatury na początku listopada.Dane wyglądają jakoś tak
Dane zawierają trzy kolumny:
entity_id
— spokojniemożna pominąć,state
— zmierzona wartość temperatury,last_changed
— czas pomiaru zapisany jako2024-10-31T23:00:00.000Z
Ponownie sugeruję skorzystanie z Import Data; pierwszej kolumny można nie importować, drugą należy zaimportować jako wartości numeryczne…
Kłopot jest z kolumną trzecią — MATLAB chce ją traktować jako tekst. Trzeba mu podpowiedzieć, że jest to obiekt typu czas (w nomenklaturze MATLABowej datetime). I tu trzeba się trochę napracować.
Format
datetime
opisany jest dalej.Import Tool prawidłowo rozpoznaje pierwsze dwie kolumny, ale trzecia traktowana jest jako tekst
Klikając w more date formats przechodzimy do miejsca, w którym można wpisać odpowiedni format danych…
Reszta powinna być już łatwa…
Zadanie 3 — nieobowiązkowe
Linię trendu można (w przypadku Zadania 2) jako informację o średniej szybkości spadku temperatury (w stopniach na jednostkę czasu).
Z matematycznego punktu widzenia, zadanie sprowadza się do aproksymowania danych za pomocą linii prostej. Służy do tego funkcja fit()
z pakietu Curve fitting toolbox (skrócony opis dalej). Niestety, nasze dane (last_changed
) są typu datetime
, a nie typu double
i funkcja ta nie chce działać… Trzeba czas skonwertować do typu double
. Służy do tego funkcja convertTo
opisana dalej.
Również funkcja fit()
opisana jest dalej…
Czasami (gdy „źle” dobierzemy format czasu) funkcja zwraca informację o postaci:
Warning: Equation is badly conditioned. Remove repeated data points or try centering and scaling.
Wyjaśnienie tego jest dosyć proste: gdy wartości $x$-ów są bardzo duże (w stosunku do $y$) odpowiedni parametr musi być bardzo mały.
W takich sytuacjach można dane „uprościć” odejmując od każdej wartości $x$ wartość minimalną (czas początkowy) czyli przesuwając wszystko na os w kierunku zera.
Albo przeskalować przedział czasu do przedziału $[0, 1]$.
detrend()
Wywołanie funkcji:
D = detrend(A)
D = detrend(A,n)
D = detrend(A,n,bp)
D = detrend(___,nanflag)
D = detrend(___,Name,Value)
D = detrend(A)
znajduje i usuwa trend opisany linią prostą;Gdy
A
jest wektorem — trend jest odejmowany od każdej wartości.Gdy
A
jest macierzą — wyliczany jest dla każdej kolumnyD = detrend(A,n)
znajduje i usuwa trend opisany wielomianem stopnian
. Gdyn
równa się zero — usuwa wartość średnią.D = detrend(A,n,bp)
jak w punkcje 2, ale tablicabp
zawiera współrzędne punktów dzielących przedział przebiegu na odcinki; dla każdego odcinka wyznaczana jest inna funkcja trendu;Użycie dodatkowego parametru (
nanflag
) pozwala zdecydować co robić z pojawiającymi się (ewentualnie) wartościamiNaN
1. Parametr może przyjmować wartości:"includemissing"
(domyślnie) |"includenan"
— pozostawia wartości NaN"omitmissing"
|"omitnan"
— odrzuca z danych wartościNaN
D = detrend(___,Name,Value)
Ta forma pozwala na zdefiniowanie dodatkowych parametrów. Dodatkowe parametry to:Continuous
(przyjmuje wartościtrue
(domyślnie) lubfalse
) decyduje czy linia trendu ma być ciągłaSamplePoints
— definiuje tablicę wartości zmiennej niezależnej2.DataVariables
— pozwala zdefiniować, na których kolummach tablicyA
ma być wykonana operacja, n.p.:detrend(A,"DataVariables",["Var1" "Var2" "Var4"])
ReplaceValues
(przyjmuje wartościtrue
lubfalse
) decyduje czy po usunięciu trendu nowe wartości mają zastąpić stare, czy mają być dodane do tablicy danych.
Użycie funkcji detrend()
może być uciążliwe ( i wymagać wykonania wielu prób i błędów). Z tego powodu można w Live script skorzystać z zadania (task)
Przechodzimy do zakładki INSERT i tam wybieramy
Task
; otwiera się lista wielu zadań, z których można skorzystać. Zwracam uwagę, że jest tu również zadanie Import Data.Wybieramy zadanie. Zostaje ono wstawione do skryptu.
W pierwszym etapie decydujemy czy usuwa,y trend wielomianowy czy okresowy (w naszym przypadku ten pierwszy)
Na kolejnym panelu możemy wybrać parametry
Zwracam uwagę na „ptaszek” w polu Autorun (prawy górny róg) — gdy jest on wstawiony wszystkie zmiany będą natychmiast przeliczane; gdy nie — trzeba kliknąć w w zielony trójkącik.
Gdy już będziemy zadowoleni z rezultatu — możemy poprosić o pokazanie kodu realizującego procedurę.
datetime()
MATLAB posiada specjalny typ danych służący do przechowywania czasu: datetime
.
Żeby zadeklarować zmienną tego typu można użyć polecenia datetimne
t = datetime;
nada zmiennej t
wartość aktualnej daty i czasu
>> t
t =
datetime
13-Nov-2024 17:40:27
Tekstowy format czasu używany w różnych miejscach na świecie i przez różne aplikacje może się bardzo różnić. Jest norma (ISO 8601), która mówi jak czas powinno się zapisywać. I najogólniejszym zapisem jest format:
YYYY-MM-DDThh:mm:ss.SSS±hh:mm
- pierwsza część (przed literą
T
) , to data, - część druga to aktualny czas (godzina, minuta, sekunda, po kropce tysięczne części sekund).
- na końcu (
±hh:mm
) to określenie strefy czasowej (określanej jako przesunięcie czasowe w stosunku do czasu Greenwich); gdy te przesunięcie jest równe00:00
może na końcu pojawić się literaZ
(czytana jako Zulu).
Funkcja datetime
pozwala również na konwersję różnych formatów czasu na format używany przez MATLABa, polecenie wygląda tak:
t = datetime(DateStrings,'InputFormat',infmt)
DateStrings
to czas zapisany w postaci tekstowejinfmt
zmienna mówiąca jak należy interpretować poszczególne znaki danych wejściowych:yyyy
rok (czetry cyfry)mm
miesiąc (dwie cyfry)dd
dzień (dwie cyfry)HH
godzina (dwie cyfry)mm
minuta (dwie cyfry)\ss
sekunda (dwie cyfry)SSS
tysięczne sekundy (trzy cyfry)
pozostałe znaki, jeżeli występują muszą wystąpić tak jak wpisano.
Czas zapisany jako "2024-10-31T23:00:00.000Z"
można opisać symboliczne tak:
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
Polecenie
czas = datetime("2024-10-31T23:00:00.000Z", 'InputFormat', "yyyy-MM-dd'T'HH:mm:ss.SSS'Z")
skonwertuje dane na standardowy (dla MATLABa) format czasu…
convertTo()
Funkcja, jest — w zasadzie — dosyć prosta. Trzeba tylko wybrać odpowiedni format wyjściowy. Formatów wyjściowych typu double używanych do reprezentacji czasu jest kilka:
excel
— Number of days since 0-Jan-1900, representing an Excel® date number.excel1904
— Number of days since 0-Jan-1904, representing an Excel date number.juliandate
— Number of days since noon UTC 24-Nov-4714 BCE in the proleptic Gregorian calendar, representing the Julian Date.modifiedjuliandate
— Number of days since midnight UTC 17-Nov-1858, representing the Modified Julian Date.posixtime
— Number of seconds since 1-Jan-1970 00:00:00 UTC, a point in time known as the Unix epoch.yyymmdd
— Dates as YYYYMMDD numeric values. For example,20140402
represents April 2, 2014. Obcina godziny!datenum
— Number of days since 0-Jan-0000 in the proleptic ISO calendar.
Przykład
>> czas = datetime("2024-10-31T23:00:00.000Z", 'InputFormat', "yyyy-MM-dd'T'HH:mm:ss.SSS'Z")
czas =
datetime
31-Oct-2024 23:00:00
>> format longg
>> czasExcel = convertTo(czas,"Excel")
czasExcel =
45596.9583333333
>> czasExcel1904 = convertTo(czas,"Excel1904")
czasExcel1904 =
44134.9583333333
>> czasposix = convertTo(czas,"posix")
czasposix =
1730415600
>> czasjuliandate = convertTo(czas,"juliandate")
czasjuliandate =
2460615.45833333
>> czasyyyymmdd = convertTo(czas,"yyyymmdd")
czasyyyymmdd =
20241031
>> czasdatenum = convertTo(czas,"datenum")
czasdatenum =
739556.958333333
>> czasmodifiedjuliandate = convertTo(czas,"modifiedjuliandate")
czasmodifiedjuliandate =
60614.9583333333
Jak się wydaje każdy (za wyjątkiem yyyymmdd
) format będzie ok.
Ja, osobiście, jestem jakoś przywiązany do posixtime
, ale Państwo mogą wybrać cokolwiek (choć początkowa data zerowy dzień stycznia jakoś mnie przeraża).
fit()
Funkcji używamy na jeden z poniższych sposobów
fitobject = fit(x,y,fitType)
fitobject = fit([x,y],z,fitType)
fitobject = fit(x,y,fitType,fitOptions)
fitobject = fit(x,y,fitType,Name=Value)
[fitobject,gof] = fit(x,y,fitType)
[fitobject,gof,output] = fit(x,y,fitType)
W tych zapisach
x
— współrzędne $x$-owey
— współrzędne $y$-owefittype
— jeden z bardzo wielu modeli, które mogą być użyte; najpopularniejsze to:poly1
— liniowypoly2
— kwadratowy- … i tak dalej aż do
poly9
można również zdefiniować swój własny model korzystając, na przykład, z funkcji anonimowej
Trzeba pamiętać, że ten parametr podajemy jako tekst to znaczy w cudzysłowach!
Funkcja zwraca wartości parametrów oraz przedziały ufności dla nich
Z fitobject
można korzystać tak jak z funkcji.
NaN
to określenie Not a Number, które pojawia się gdy nie można określić wartości operacji arytmetycznej (na przykładInf - INf
czyli $\infty-\infty$ ); w przypadku danych pomiarowych tak oznacza się brakujące dane. ↩︎Współrzędne $x$-owe danych są bardzo istotne, gdy dane są próbkowane niejednostajnie. Czemu? Oczekuję odpowiedzi na te pytanie w sprawozdaniu. ↩︎