Pętla for w Octave

advertisement
Pętla for w Octave
Roman Putanowicz
13 kwietnia 2008
1
Zakresy i operator “:”
Zakresy (ang. ranges) są wygodnym sposobem definiowania wektorów reprezentujących ciągi arytmetyczne, czyli ciągi w których różnica pomiędzy dwoma kolejnymi elementami jest stała. Wyrażenie będące
zakresem określone jest przez podanie wartości początkowej ciągu, opcjonalnie przyrostu elementów ciągu
oraz maksymalnej wartości (tzw. kresu górnego), której nie mogą przekroczyć elementy ciągu. Wartość
początkową, przyrost i kres górny podaje się odesparowane dwukropkiem ’:’.
wartość początkowa : przyrost : kres górny
Jeżeli przyrost nie zostanie podany domyślnie przyjmowana jest wartość 1. Przykłady:
octave:1> 1:2:9
ans =
1 3 5 7 9
octave:2> 1:7
ans =
1 2 3 4 5
6
7
Podanie negatywnej wartości przyrostu wraz z odpowiednią wartością kresu górnego pozwala na definiowanie ciągu o wartościach malejących:
octave:3> 10:-1:0
ans =
10
9
8
7
6
5
4
3
2
1
0
Wszystkie trzy wielkości definiujące zakres, to jest wartość początkowa, przyrost i kres górny mogą być
wartościami rzeczywistymi:
octave:4> 1.5:0.3:3.7
ans =
1.5000 1.8000 2.1000 2.4000 2.7000 3.0000 3.3000 3.6000
Uwaga: w przypadku użycia w definicji zakresu wartości rzeczywistych kres górny może nie
być uwzględniany w wyniku, nawet jeżeli przyrost mieści się całkowitą liczbę razy w przedziale wyznaczonym przez wartość początkową i kres górny (np. 1:0.2:3). Dzieje się tak na skutek
błędów zaokrągleń przy operowaniu liczbami rzeczywistymi. Jeżeli konieczna jest gwarancja by wartości skrajne zakresu były uwzględnione w wyniku, należy skorzystać z funkcji
linspace.
Zakresy są interpretowane jako wektory wierszowe, z tym, że jeżeli nie ma potrzeby Octave nie skonwertuje zakresu do wektora, oszczędzając tym samym na pamięci potrzebnej na przechowywanie elementów
wektora.
octave:5> a = 1:4
a =
1 2 3 4
octave:6> isvector(a)
ans = 1
octave:7> size(a)
ans =
1 4
1
Każda z wielkości definiujących zakres może być podana jako dowolne wyrażenie arytmetyczne lub
wywołanie funkcji:
octave:8> i=2;
octave:9> 1-0.5 : sin(0.9) : i^2
ans =
0.50000 1.28333 2.06665 2.84998 3.63331
2
Instrukcja for
Instrukcja for ma następującą składnię:
for zmienna = wyrażenie
instrukcje
endfor
gdzie: instrukcje oznacza jedną lub więcej instrukcji, zmienna oznacza nazwę zmiennej a wyrażenie oznacza
jakiekolwiek poprawne wyrażenie. Instrukcja for działa w ten sposób, że zmiennej przypisywane są kolejne
kolumny wyrażenia. Jeżeli wynikiem wyrażenia jest wektor wierszowy to zmienna będzie skalarem i będzie
przyjmowała kolejne wartości elementów wektora. Po przypisaniu zmiennej kolejnej wartości wykonywane
są instrukcje. Przykłady:
octave:10> for i=1:4
> disp(i);
> endfor
1
2
3
4
octave:11> for i=[7,3,2,8]
> disp(i);
> endfor
7
3
2
8
octave:12> v = [1,3,4,5]
v =
1 3 4 5
octave:13> for i = v
> disp(i);
> endfor
1
3
4
5
2.1
Przykłady
Wypisywanie kolejnych liczb nieparzystych
Napisz skrypt, który będzie wypisywał N kolejnych liczb nieparzystych, przy czym wartość N podaje
użytkownik. Zadanie to można rozwiązać na dwa sposoby:
Sposób 1 – policzyć jaka ma być maksymalna liczba nieparzysta, którą trzeba wypisać i skorzystać z instrukcji zakresu tak by od razu generowała żądany ciąg:
N = input("Podaj ilosc liczb nieparzystych : ");
maxnp = 2*N-1;
for i=1:2:maxnp
disp(i);
endfor
Powyższy skrypt zapisujemy w pliku o nazwie np.m a następnie uruchamiamy poleceniem:
octave -q np.m
2
Sposób 2 – wykorzystać związek między indeksem (kolejnym numerem) liczby nieparzystej a jej wartością:
N = input("Podaj ilosc liczb nieparzystych : ");
for i=1:N
v = 2*i - 1;
disp(v);
endfor
Wypisywanie kolejnych elementów ciągu arytmetycznego
Ciąg arytmetyczny to taki ciąg, w którym różnica dwu kolejnych argumentów jest stała. Przy tym
założeniu można wyprowadzić wzór:
ai = a0 + i ∗ r
gdzie a0 jest wyrazem początkowym, i indeksem elementu, a r różnicą ciągu.
n = input("Podaj
r = input("Podaj
a = input("Podaj
for i=0:n-1
v = a = i*r;
printf("a_%d =
endfor
ilość elementów ciągu : ")
różnicę ciagu : ")
element początkowy : ")
%g\n", i, v);
Powyższy skrypt zapisujemy w pliku o nazwie artymet.m i uruchamiamy poleceniem:
octave -q arytmet.m
Wypisywanie elementów wektora większych niż określona wartość
Napisz skrypt, który poprosi użytkownika o podanie wektora oraz wartości granicznej, a następnie
wypisze tylko te elementy wektora, które są większe niż wartość graniczna.
v = input("Podaj wektor (np: [1,3,4]) : ");
g = input("Podaj wartosc graniczna : ");
printf("Elementy wektora wieksze niz %g\n", g);
n = length(v);
for i = 1:n
if (v(i) > g)
printf("v_%d : %g\n", i, v(i));
endif
endfor
3
Podstawowe algorytmy
W tym punkcie zostaną omówione dwa podstawowe algorytmy: algorytm przeglądnięcia elementów ciągu
i akumulacji rezultatów operacji na przeglądanych elementach oraz algorytm znajdowania maksymalnego
(minimalnego) elementu ciągu.
3.1
Notacja Σ i Π
W celu zwartego zapisywania wyrażeń będących sumą kolejnych elementów ciągu wprowadza się notację
Σ:
n
X
i = 0 + 1 + 2 + . . . + (n − 1) + n
i=0
3
Przykłady:
3
X
(i + 1)2 = (0 + 1)2 + (1 + 1)2 + (2 + 1)2 + (3 + 1)2
2
X
(m + i) = (m + 0) + (m + 1) + (m + 2)
3
X
a·i = a·1+a·2+a·3 =a
i=0
i=0
3
X
iprzy założeniu, że a =const
i=1
i=1
Na podobnej zasadzie działa notacja Π. Oznacza ona iloczyn kolejnych elementów ciągu:
n
Y
i = 1 · 2 · . . . · (n − 1) · n
3
Y
i= 1·2·3= 6
i=1
Przykłady:
i=1
3
Y
i2 = 1 2 · 2 2 · 3 2 = 1 · 4 · 9
i=1
Nietrudno zauważyć następujący związek:
n
Y
i = n!
i=1
3.2
Implementacja wyrażeń zawierających
P
P
Chcąc w programie komputerowym obliczyć wyrażenie zawierające
musimy skonstruować algorytm,
który będzie akumulował (gromadził) wartości kolejnych elementów sumy. Trzy podstawowe elementy
tego algorytmu to:
• przypisanie wartości 0 do zmiennej, która będzie reprezentować sumę (zero dlatego, że nie dodaliśmy
jeszcze żadnego elementu),
• wygenerowanie kolejnych elementów sumy,
• uaktualnienie sumy przez dodanie do starej wartości sumy nowego elementu.
Pn
Poniżej zamieszczono przykład programu, który oblicza wartość wyrażenia i=1 i2 dla n podanego przez
użytkownika
n = input("Podaj n : ");
suma = 0;
for i = 1:n
suma = suma + i^2;
endfor
printf("Wartosc sumy : %g\n", suma);
3.3
Implementacja wyrażeń zawierających
Implementacja wyrażeń zawierających
Q
Q
jest analogiczna do tej dla
P
:
• Inicjalizacja zmiennej, która będzie reprezentować iloczyn wartością 1 (jeden dlatego, że jest to
wartość neutralna dla mnożenia, tak jak 0 jest wartością neutralną dla dodawania).
• Wygenerowanie kolejnych elementów iloczynu
• Uaktualnienie iloczynu przez pomnożenia starej wartości iloczynu przez kolejny element.
Qn
Poniżej zamieszczono przykład programu, który oblicza n! = i=1 i
4
n = input("Podaj n : ");
iloczyn = 1;
for i = 1:n
iloczyn = iloczyn * i;
endfor
printf("Wartosc n! : %g\n", iloczyn);
3.4
Znajdowanie maksymalnego elementu ciagu
Algorytm znajdowania maksymalnego elementu ciągu składa się z następujących kroków:
1. przyjmij pierwszy element ciągu jako element maksymalny,
2. przeglądaj następne elementy – jeżeli któryś z nich jest większy niż przyjęty element maksymalny
to zastąp nim element maksymalny.
Poniżej zamieszczono przykład programu znajdującego maksymalny element w wektorze (w Octave używamy wektorów do reprezentowania ciągów o skończonej liczbie elementów)
v = input("Podaj wektor : ");
n = length(v);
max = v(1);
for i = 2:n
if max < v(i)
max = v(i);
endif
endfor
printf("Maksymalny element wektora to : %g\n", max);
4
Zadania różne
Poniżej przedstawiono przykłady różnych zadań wymagających użycia pętli.
Obliczanie iloczynu skalarnego wektorów
Napisz skrypt, który obliczy iloczyn skalarny wektorów nie korzystając z operatora “*” w odniesieniu
do wektorów. Iloczyn skalarny można wyrazić przez współrzędne jako:
X
vi · ui
v◦u=
i
Skrypt realizujący powyższe obliczenia:
v = input("Podaj wektor v : ");
u = input("Podaj wektor u : ");
n = length(v);
s = 0;
for i = 1:n
s = s + v(i) * u(i);
endfor
printf("Skalarnie v*u = %g\n", s);
Rysowanie wielokąta foremnego
Napisz skrypt, który narysuje N -kąt foremny wpisany w okrąg o promieniu R. Patrząc na rysunek
można łatwo zauważyć, że współrzędne N-kąta foremnego dane są wzorem:
2π · (i − 1)
)
N
2π · (i − 1)
)
yi = R · sin(
N
xi = R · cos(
gdzie i = 1, . . . , N .
5
y
2
3
β
4
1
x
6
5
N = input("Podaj ilosc bokow n=")
R = input("Podaj promien okregu R=")
beta = 2*pi/N;
for i = 1:N+1
x(i) = R * cos(beta * (i-1));
y(i) = R * sin(beta * (i-1));
endfor
axis("square");
plot(x,y, "@-");
pause()
5
Ćwiczenia
1. Napisz skrypt, który będzie wypisywał wszystkie liczby nieparzyste w przedziale [2, 49] ale od największej do najmniejszej.
2. Napisz skrypt, który wypisze sześciany N początkowych liczb nieparzystych. N podaje użytkownik.
3. Napisz skrypt, który dla podanego przez użytkownika wektora wypisze tylko te elementy, które są
ujemne.
4. Napisz skrypt, który dla podanego przez użytkownika wektora obliczy sumę elementów ujemnych.
5. Napisz skrypt, który obliczy długość euklidesową dowolnego n-wymiarowego wektora. Długość ta
dana jest wzorem:
q
||v|| = v12 + v22 + . . . + vn2
6. Napisz skrypt, który znajdzie indeks minimalnego elementu wektora.
6
Download