Skip to end of metadata
Go to start of metadata

Kodeforståelsesoppgaver (total videotid: 33:13)

Oppgave 4.1.1: Fprintf datatyper

Hva skrives ut hvis vi kjører dette scriptet?
oppgave_1.m
fprintf('Heltallet er %d\n', 1);
fprintf('Desimaltallet er %f\n', 2.5);
fprintf('Bokstaven er %c\n', 'a');
fprintf('Strengen er %s\n', 'hei');
fprintf('%d\n', 'a');
fprintf('%c\n', 97);
fprintf('\nHan sa:\n\t''Vi må gi 100 %%!''\n');

Videoforklaring (14:11)

 

Svar

 Hvis du har prøvd selv, trykk her for å se svaret...
Heltallet er 1
Desimaltallet er 2.500000
Bokstaven er a
Strengen er hei
97
a
Han sa:
	'Vi må gi 100 %!'

Oppgave 4.1.2: Fprintf utskriftsformattering

 

Hva skrives ut hvis vi kjører dette scriptet?
oppgave_2
fprintf('%3d,', 1);
fprintf('%03d,', 1);
fprintf('%-3d,', 1);
fprintf('%-03d!\n', 1);
fprintf('%.2f,', 2.524);
fprintf('%6.2f,', 2.524);
fprintf('%06.2f,', 2.524);
fprintf('%-6.2f,', 2.524);
fprintf('%-06.2f!\n', 2.524);
fprintf('%5s,', 'hei');
fprintf('%05s,', 'hei');
fprintf('%-5s,', 'hei');
fprintf('%-05s!\n', 'hei');

Videoforklaring (13:23)

Svar

 Hvis du har prøvd selv, trykk her for å se svaret...
  1,001,1  ,1  !
2.52,  2.52,002.52,2.52  ,2.52  !
  hei,00hei,hei  ,hei00!

Oppgave 4.1.3: Fprintf med vektorer

 

Hva skrives ut hvis vi kjører dette scriptet?
oppgave_3.m
fprintf('Jeg teller til %d\n', 1:5);
fprintf('Gi meg en %c\n', 'matlab');
fprintf('Gi meg en %s\n', 'matlab');

Videoforklaring (5:39)

Svar

 Hvis du har prøvd selv, trykk her for å se svaret...
Jeg teller til 1
Jeg teller til 2
Jeg teller til 3
Jeg teller til 4
Jeg teller til 5
Gi meg en m
Gi meg en a
Gi meg en t
Gi meg en l
Gi meg en a
Gi meg en b
Gi meg en matlab

Kodeoppgaver (total videotid: 54:54)

Oppgave 4.2.1: Penere Fahrenheit-utskrift

I tidligere oppgaver lagde vi et script som produserer en oversikt over hvilke Fahrenheit-verdier som tilsvarer en rekke Celsius-referanseverdier. Fahrenheit-oversikten forteller oss ikke hvilken Celsius verdi de utskrevne Fahrenheit-verdiene tilsvarer. Utvid scriptet til å skrive ut en mer informativ linje som forklarer hvilken Celsius-verdi Fahrenheit-verdien tilsvarer.

Utdelt kode

 fahrenheit.m
fahrenheit.m
svar = input('Ønsker du å skrive inn egne Celsius-verdier? (ja/nei) ', 's');
if strcmp(svar, 'ja')
    antall = input('Hvor mange verdier? ');
    for i = 1:antall
        celsius = input('Skriv inn Celsius-verdi: ');
        cels2fahr(celsius)
    end
else
    cels2fahr(-20);
    cels2fahr(0);
    cels2fahr(18);
    cels2fahr(37);
    cels2fahr(100);
end 

Videoforklaring (7:23)

Løsningsforslag

 Hvis du har prøvd selv, trykk her for å se svaret...
fahrenheit.m
svar = input('Ønsker du å skrive inn egne Celsius-verdier? (ja/nei) ', 's');
if strcmp(svar, 'ja')
    antall = input('Hvor mange verdier? ');
    for i = 1:antall
        celsius = input('Skriv inn Celsius-verdi: ');
        skriv_ut_fahr(celsius);
    end
else
    skriv_ut_fahr(-20);
    skriv_ut_fahr(0);
    skriv_ut_fahr(18);
    skriv_ut_fahr(37);
    skriv_ut_fahr(100);
end
skriv_ut_fahr
 

Oppgave 4.2.2: Kvadratrotestimat

 

Du stoler ikke på at Matlabs innebygde funksjon sqrt er effektiv nok, og har funnet ut at du vil lage din egen. Du har innsett at siden

\( rot^2 = tall \Rightarrow tall - rot^2 = 0 \)

, blir det å finne kvadratroten til et tall det samme som å finne nullpunktet til funksjonen

\( f(rot) = tall - rot^2 \)

 . Du har lært en metode for å finne nullpunkt, kalt Newtons metode, som fungerer slik:
  1.  Velg et første estimat for nullpunkt, \( x_0 \) , for funksjonen \( f(x) \) .

  2. Regn ut videre estimat for nullpunkt med formelen \( x_{i+1} = x_i - \frac{f(x_i)}{f'(x_i)} \)

(I vårt tilfelle er \( f'(x) = 2x \) ).

Lag en funksjon som estimerer roten til et tall. Bruk 20 iterasjoner av Newtons metode, og \( x_0 = 1 \) . Sammenlign estimatene for kvadratroten av 4, 97 og 1e18 med estimatene fra sqrt.

Videoforklaring (9:02)

Løsningsforslag

 Hvis du har prøvd selv, trykk her for å se svaret...
kvadratrot.m
function retur = kvadratrot(tall)
    x = 1;
    for i = 1:20
       x = x + (tall - x^2)/(2*x);
    end
    retur = x;
end

Oppgave 4.2.3: Utskrift av progresjon i kvadratrotestimat

 

Du har nettopp laget en funksjon som estimerer kvadratroten til et tall, ved hjelp av 20 iterasjoner av Newtons metode. Du ønsker nå å vite hvordan utviklingen av estimatene er i hver iterasjon. Utvid funksjonen til å produsere utskrift som det følgende i hver iterasjon:

Utdelt kode

 kvadratrot.m
kvadratrot.m
function retur = kvadratrot(tall)
    x = 1;
    for i = 1:20
       x = x + (tall - x^2)/(2*x);
    end
    retur = x;
end

Videoforklaring (7:25)

Løsningsforslag

 Hvis du har prøvd selv, trykk her for å se svaret...
kvadratrot.m
function retur = kvadratrot(tall)
    x = 1;
    for i = 1:20
       ny_x = x + (tall - x^2)/(2*x);
       fprintf('Iterasjon #%d: x_%d = %.10f, x_%d = %.10f\n', i, i-1, x, i, ny_x);
       x = ny_x;
    end
    retur = x;
end

Oppgave 4.2.4: Trygg innlesing av tall fra bruker

 

Du har innsett at å bruke Matlabs input-funksjon uten å bruke 's'-parameteren er en sikkerhetsrisiko, siden den lar brukeren kjøre vilkårlig Matlab-kode. Du synes også at feilmeldingene som dukker opp hvis brukeren skriver inn et ugyldig tall er dårlige.

Lag en ny funksjon som leser inn og returnerer et tall fra brukeren. For at funksjonen skal kunne brukes så generelt som mulig, skal teksten som spør brukeren om å skrive inn et tall være en parameter. Funksjonen må bruke to-parameter-versjonen av input. Hvis brukeren skriver inn et ugyldig tall, skal funksjonen skrive ut en passende feilmelding og prøve å lese inn et tall på nytt.

Videoforklaring (12:14)

Løsningsforslag

 Hvis du har prøvd selv, trykk her for å se svaret...
les_inn_tall.m
function retur = les_inn_tall(melding)
    tallstr = input(melding, 's');
    tall = str2double(tallstr);
    er_ugyldig = isnan(tall);
    while er_ugyldig
        fprintf('Teksten %s kan ikke tolkes som et tall\n', tallstr);
        tallstr = input(melding, 's');
        tall = str2double(tallstr);
        er_ugyldig = isnan(tall);
    end
    retur = tall;
end

Oppgave 4.2.5: Fahrenheit-script med uvisst antall referanseverdier

 

Tidligere lagde du et script som lot brukeren skrive inn en rekke Celsius-verdier, og konverterte én og én til Fahrenheit. I scriptet måtte brukeren bestemme seg på forhånd for hvor mange Celsius-verdier som skulle skrives inn.

Endre scriptet slik at brukeren kan skrive inn et vilkårlig antall Celsius-verdier. Hvis brukeren trykker enter uten å skrive noe, skal scriptet avslutte. 

Utdelt kode

 fahrenheit.m
fahrenheit.m
svar = input('Ønsker du å skrive inn egne Celsius-verdier? (ja/nei) ', 's');
if strcmp(svar, 'ja')
    antall = input('Hvor mange verdier? ');
    for i = 1:antall
        celsius = input('Skriv inn Celsius-verdi: ');
        skriv_ut_fahr(celsius);
    end
else
    skriv_ut_fahr(-20);
    skriv_ut_fahr(0);
    skriv_ut_fahr(18);
    skriv_ut_fahr(37);
    skriv_ut_fahr(100);
end 
 skriv_ut_fahr.m
skriv_ut_fahr.m
function skriv_ut_fahr(celsius)
    fahr = cels2fahr(celsius);
    fprintf('Celsiusverdi %.2f tilsvarer Fahrenheitverdi %.2f\n', celsius, fahr);
end 
 les_inn_tall.m
les_inn_tall.m
function retur = les_inn_tall(melding)
    tallstr = input(melding, 's');
    tall = str2double(tallstr);
    er_ugyldig = isnan(tall);
    while er_ugyldig
        fprintf('Teksten %s kan ikke tolkes som et tall\n', tallstr);
        tallstr = input(melding, 's');
        tall = str2double(tallstr);
        er_ugyldig = isnan(tall);
    end
    retur = tall;
end 

Videoforklaring (10:25)

Løsningsforslag

 Hvis du har prøvd selv, trykk her for å se svaret...
fahrenheit.m
svar = input('Ønsker du å skrive inn egne Celsius-verdier? (ja/nei) ', 's');
if strcmp(svar, 'ja')
    celsius = les_inn_tall('Skriv inn Celsius-verdi: ');
    while ~isempty(celsius)
        skriv_ut_fahr(celsius);
        celsius = les_inn_tall('Skriv inn Celsius-verdi: ');
    end
else
    skriv_ut_fahr(-20);
    skriv_ut_fahr(0);
    skriv_ut_fahr(18);
    skriv_ut_fahr(37);
    skriv_ut_fahr(100);
end 
les_inn_tall.m
function retur = les_inn_tall(melding)
    tallstr = input(melding, 's');
    tall = str2double(tallstr);
    er_ugyldig = isnan(tall);
    while er_ugyldig && ~isempty(tallstr)
        fprintf('Teksten %s kan ikke tolkes som et tall\n', tallstr);
        tallstr = input(melding, 's');
        tall = str2double(tallstr);
        er_ugyldig = isnan(tall);
    end
    if isempty(tallstr)
        retur = [];
    else
        retur = tall;
    end
end 

Oppgave 4.2.6: Sikrere kvadratrotestimat med feiltoleranse

Tidligere lagde du en funksjon som estimerte kvadratroten av et tall ved å bruke et fast antall iterasjoner av Newtons metode. Du har imidlertid innsett at dette gir unøyaktige svar i noen tilfeller, og unødvendig mange iterasjoner i andre tilfeller. Du ønsker derfor å tilpasse antall iterasjoner til verdien vi skal estimere kvadratroten av. En måte å gjøre dette på, er å kjøre Newtons metode helt til relativ endring av verdien er mindre enn en viss grense. Formelen for relativ endring, er

\( \epsilon = \frac{\lvert x_{i+1} - x_i \rvert}{x_i} \)

.

Endre funksjonen til å regne ut kvadratrot med en relativ feilgrense på 1e-9.

Utdelt kode

 kvadratrot.m
kvadratrot.m
function retur = kvadratrot(tall)
    x = 1;
    for i = 1:20
       ny_x = x + (tall - x^2)/(2*x);
       fprintf('Iterasjon #%d: x_%d = %.10f, x_%d = %.10f\n', i, i-1, x, i, ny_x);
       x = ny_x;
    end
    retur = x;
end

Videoforklaring (8:25)

Løsningsforslag

 Hvis du har prøvd selv, trykk her for å se svaret...
kvadratrot.m
function retur = kvadratrot(tall)
    x = 1;
    er_over_feilgrense = true;
    i = 1;
    while er_over_feilgrense
       ny_x = x + (tall - x^2)/(2*x);
       fprintf('Iterasjon #%d: x_%d = %.10f, x_%d = %.10f\n', i, i-1, x, i, ny_x);
       relativ_endring = abs(ny_x - x)/x;
       er_over_feilgrense = relativ_endring >= 1e-9;
       x = ny_x;
       i = i + 1;
    end
    retur = x;
end

  • No labels