Projekt 3

Opis projektu

Zadanie

Zadanie polega na napisaniu funkcji tworzącej losowe próby dla wartości z zaburzonych wielomianów. Rozwiązanie musi zawierać również wizualizacje uzyskanych wyników dla różnych rozkładów zaburzenia. Ściśle, w zadaniu należy zaimplementować funkcję genExampleData(), która przyjmuje nastepujące argumenty

  • coefs wektor zawierający współczynniki wielomianu, wartość domyślna to c(0);
  • n liczba punktów, które będą zaburzane;
  • ndefault liczba punktów reguralnej siatki; wartości domyślna to 100
  • ndistr funkcja zwracająca n losowych współrzędnych \( x \); w ramach tej funkcji implementowane są różne rozkłady; wartość domyślna to standardowy rozkład normalny;
  • errdistr funkcja zwracająca n losowych zaburzeń, które dodawane są do wartości wielomianu policzonych w wylosowanych współrzędnych \( x \); w ramach tej funkcji implementowane są różne rozkłady zaburzeń; wartość domyślna to standardowy rozkład normalny.

Funkcja zwraca listę zawierająca dwa sloty: sample, poly. Slot sample zawiera tibble'a z kolumnami x współrzędne \( x \) losowych punktów), y wartości wielomianu w losowych punktach, yerr wartości wielomiany w losowych punktach z dodanymi zaburzeniami. Slot poly zawiera tibble'a z kolumnami x wartości współrzędnych \( x \) na regularnej siatce zawierającej ndefault punktów, y wartości wielomianu na regularnej siatce.

Z matematycznego punktu widzenia wielomian \( w(x) \) jest zadawany jako wektor współczynników. Przykładowo

  • wieloman stały \( w(x) = 0 \) jest zapisywany jako c(0);
  • wieloman stały \( w(x) = 3 \) jest zapisywany jako c(3);
  • wielomian liniowy \( w(x) = x \) jest zapisywany jako c(0, 1);
  • wielomian postaci \( w(x) = 1 + 4 x + 2 x^2 \) jest zapisywany jako c(1, 4, 2).

Funkcja ma zwracać dwie ramki danych (tibble) opakowane w listę. Pierwsza ramka danych zawiera dane losowe wygenerowane na bazie podanego wielomianu. Dane te są generowane w dwóch krokach. W pierwszym kroku generowane są współrzędne \( x \) losowych punktów. Liczba tych punktów jest podawana w argumencie n i jest losowana zgodnie z funkcją podaną w argumencie ndistr. Następnie obliczane są wartości podanego wielomianu, do których dodawane są losowe wartości generowane zgodnie z funkcją podaną w argumencie errdistr. Druga ramka jest generowana standardowo ale w oparciu o wygenerowane losowe współrzędne \( x \). Na odcinku od minimum do maximum losowych współrzędnych \( x \) tworzona jest regularna siatka o ndefault punktach, w których liczone są wartości wielomianu dając współrzędne \( y \). Dane te są zwracane w drugiej ramce danych w slocie poly.

Przykładowe zastosowania takiej funkcji są pokazane poniżej.

### Przykład zastosowania
poly <- genExampleData(n = 300)

head(as.data.frame(poly$sample))
head(as.data.frame(poly$poly))

           x y       yerr        err
1 -0.8542428 0 -0.7834929 -0.7834929
2 -1.3118792 0 -0.4883546 -0.4883546
3  0.5250629 0  1.3606850  1.3606850
4 -0.6485424 0  0.0802476  0.0802476
5  1.3004887 0  0.7376710  0.7376710
6  0.2743772 0 -1.5253167 -1.5253167
          x y
1 -2.392236 0
2 -2.334150 0
3 -2.276063 0
4 -2.217976 0
5 -2.159890 0
6 -2.101803 0

Mając wygenerowane przykładowe dane może zrobić prostą wizualizację.

ggplot(poly$poly) +
    geom_line(aes(x, y), alpha = 0.2, color = "black") +
    geom_point(data = poly$sample, mapping = aes(x, y), color = "blue") +
    geom_point(data = poly$sample, mapping = aes(x, yerr, size = abs(err), alpha = abs(err)), color = "red")
dev.copy(device = png, "./fig1.png")
dev.off()

fig1.png

Figure 1: Przykład wygenerowanej próby

W powyższym przykładzie, w części związanej z wizualizacją, jak zwykle proszę pominąć dwie ostatnie linijki kodu, które pozwalają zapisać tworzony wykres do pliku. Jak widać, jeżeli podamy jedynie liczbę punktów to w części losowej uzyskamy punkty, który współrzędna \( x \) jest zadana standardowym rozkładem normalnym, podobnie jak wartość współrzędnej \( y \).

W kolejnym przykładzie zaburzmy wielomian \( w(x) = x + x^2 \). W pierwszej kolejności tworzymy próbkę ze standardowym rozkładami normalnymi.

poly <- genExampleData(n = 300, coefs = c(0, 1, 1))

W następnej kolejności wizualizujemy uzyskane dane.

ggplot(poly$poly) +
    geom_line(aes(x, y), alpha = 0.2, color = "black") +
    geom_point(data = poly$sample, mapping = aes(x, y), color = "blue") +
    geom_point(data = poly$sample, mapping = aes(x, yerr, size = abs(err), alpha = abs(err)), color = "red")
dev.copy(device = png, "./fig2.png")
dev.off()

Otrzymane dane wyglądają w następujący sposób.

fig2.png

Figure 2: Przykład wygenerowanej próby

Ostatecznie możemy wykorzystać dwa wywołania funkcji genExampleData() dla tego samego wielomianu ale z różnymi typami szumu aby jest porównać. Poniżej jest taki przykład.

poly1 <- genExampleData(n = 100, coefs = c(0, 1, 1), ndistr = function(n) {rnorm(n, 0, .5)})
poly2 <- genExampleData(n = 100, coefs = c(0, 1, 1), ndistr = function(n) {rnorm(n, 0, 3)})

ggplot() +
    geom_line(data = poly2$poly, mapping = aes(x = x, y = y), alpha = 0.2, color = "black") +
    geom_point(data = poly2$sample, mapping = aes(x = x, y = y), color = "blue", alpha = .5) +
    geom_point(data = poly2$sample, mapping = aes(x, yerr, alpha = abs(err)), color = "blue") +
    geom_point(data = poly1$sample, mapping = aes(x = x, y = y), color = "red", alpha = 0.5) +
    geom_point(data = poly1$sample, mapping = aes(x = x, y = yerr), color = "red")
dev.copy(device = png, "./fig3.png")
dev.off()

fig3.png

Figure 3: Przykład wygenerowanej próby

W ostatnim przykładzie wykorzystamy inny wielomian i dwa inne rozkłady zarówno jeżeli chodzi o współrzędne \( x \) jak i zaburzenia.

poly <- genExampleData(n = 1000,
		       coefs = c(0, 1, -10, .5) / 10,
		       ndistr = function(n) {rgamma(n, shape = 5)},
		       errdistr = function(n) {rnorm(n, 10, 10)})

ggplot() +
    geom_line(data = poly$poly, mapping = aes(x = x, y = y), alpha = 0.2, color = "black") +
    geom_point(data = poly$sample, mapping = aes(x = x, y = y), color = "blue", alpha = .5) +
    geom_point(data = poly$sample, mapping = aes(x, yerr, alpha = abs(err)), color = "red", shape = "+", size = 5)
dev.copy(device = png, "./fig4.png")
dev.off()

Uzyskane wyniki wyglądają w następujący sposób.

fig4.png

Figure 4: Przykład wygenerowanej próby

Podsumowując, zadanie polega na zaproponowaniu implementacji funkcji genExampleData() oraz zbudowaniu wizualizacji (być może takich jak powyżej ale wykorzystanie pakietu ggplot2 nie jest obowiązkowe).

Techniczne warunki zaliczenie

Zadanie powinno być rozwiązane w pojedynczym skrypcie w pliku R. Rozwiązanie powinno zawierać definicję wymaganej funkcji oraz przykładowe wykorzystanie (zgodnie z treścią zadania). Rozwiązania bez przykładów nie będą zaliczane. W rozwiązaniu nie wolno wykorzystywać dodatkowych pakietów poza pakietami dplyr oraz ggplot2, a jedynie dozwolone symbole to ASCII.

Data: 2021-04-09 Fri 00:00

Autor: Michał Ramsza

Created: 2021-04-09 Fri 14:54

Validate