Föreläsningar 9, 10 (okt 01, okt 03 v 40).

delvis DD Chapter 7.

Vad som menas med arrayer, element och [] se DD 7.1, 7.2, 7.3. Arrayer som parametrar DD 7.5, 7.6. Jag kommer att förklara samma sak med nedanstående exempel, som mycket liknar den viktigaste hemuppgiften. DD 7.4 innehåller en massa andra exempel.

Komplexa tal som arrayer

Vi ska implementera algebra för komplexa tal i en klass Comp med hjälpa av tvåkomponentsarrayer. I klassen skall finnas definitioner för de statiska metoder som finns i detta diagram:

Detta kan göras på detta vis:

En komplext tal är i vår lösning (vi ska kommande veckor göra på många andra sätt, bättre sätt) en tvåkomonetsarray med realdelen i komponent [0] och imaginärdelen i [1].

public class Comp {

public static double [] mkComplex(double re, double im) {

double [] result = new double [2];

result[0] = re;

result[1] = im; // BILD NEDAN HUR DET SER UT HÄR

return result;

}

public static boolean isEqual(double [] z1, double [] z2){

return (z1[0] == z2[0]) && (z1[1] == z2[1]);

}

public static double [] add(double [] z1, double [] z2){

/*

double [] result = new double [2];

result[0] = z1[0] + z2[0];

result[1] = z1[1] + z2[1];

return result;

*/

return mkComplex( z1[0] + z2[0], z1[1] + z2[1]);

}

public static double [] sub(double [] z1, double [] z2){

return mkComplex( z1[0] - z2[0], z1[1] - z2[1]);

}

public static double [] mult(double [] z1, double [] z2){

return mkComplex(z1[0]*z2[0] - z1[1]*z2[1],

z1[0]*z2[1] + z1[1]*z2[0]);

}

public static double [] conjugate(double [] z1){

return mkComplex( z1[0], - z1[1]);

}

public static double modulus(double [] z1){

return Math.sqrt(z1[0]*z1[0] + z1[1]*z1[1]);

}

public static double [] div(double [] z1, double [] z2){

if (isEqual(z2, mkComplex(0,0))) {

throw new RuntimeException("Tried to divid by 0 + 0i");

} else {

double mo = modulus(z2);

double dd = mo*mo;

double [] zz = mult(z1, conjugate(z2));

return mkComplex( zz[0]/dd, zz[1]/dd);

}

}

public static double re(double [] z1){

return z1[0];

}

public static double im(double [] z1){

return z1[1];

}

public static String toString(double [] z1) {

return z1[0] + " + " + z1[1] + "i";

}

}

Vi kan nu göra beräkningar på komplexa tal på detta vis :

public class TestComplex {

public static void main(String [] iargs) {

System.out.println(" (3+4i)= " +

Comp.toString(Comp.mkComplex(3, 4)));

System.out.println(" (3+4i)/(1-2i) = " + Comp.toString(

Comp.div(Comp.mkComplex(3, 4),

Comp.mkComplex(1, -2))));

System.out.println(" (3+2i)(4+5i) = " + Comp.toString(

Comp.mult(Comp.mkComplex(3, 2),

Comp.mkComplex(4, 5))));

System.out.println(" Ex 10.2.14 = " +

Comp.toString(

Comp.sub(

Comp.div(Comp.mkComplex(1, -2),

Comp.mkComplex(3, 4)),

Comp.div(Comp.mkComplex(2, 1),

Comp.mkComplex(0, 5)))));

}

}

Om vi i en metod gör denna deklaration double [] result händer detta:

Om vi i en metod gör detta: eller (samma sak):

double [] result; double [] result =new double [2];

result = new double [2];

händer detta:

I resten av metoden kan vi i uttryck använda resultat[0] och resultat[1] för

att räkna på komponternas värden, och resultat[0] = .. och resultat[1] = ..

för att ge komponeterna nya värden.

Så här ser det ut i datorn just före

return result;

i metoden mkComplex när main gjort anropet Comp.mkComplex(3, 4)).

Körresultat när vi kör TestComplex :

(3+4i)= 3.0 + 4.0i

(3+4i)/(1-2i) = -0.9999999999999998 + 1.9999999999999996i

(3+2i)(4+5i) = 2.0 + 23.0i

Ex 10.2.14 = -0.4 + 0.0i

Matriser

Matriser se avsnitt DD 7.9 . Ett exmpel på matrisaddition:

public class Matrisalgebra1 {

public static void main(String [] iargs) {

double [][] mA = {

{0, 0},

{2, 4},

{5, 2}

};

double [][] mB = {

{1, 1},

{1, 1},

{1, 2}

};

System.out.println("mA : ");

System.out.println();

print(mA);

System.out.println();

System.out.println("mB ");

System.out.println();

print(mB);

System.out.println();

System.out.println("mA + mB ");

System.out.println();

print(add(mA, mB));

}

..... print(.....

public static double [][] add(double [][] m1, double [][] m2 ) {

if ((m1.length != m2.length) &&

((m1[0]).length != (m2[0]).length)) {

throw new RuntimeException("felaktiga matrisstorlekar");

}

double [][] newM

= new double [m1.length] [(m1[0]).length];

for(int i = 0; i < m1.length; i = i+1) {

for(int j = 0; j < (m1[0]).length; j = j+1) {

newM[i][j] = m1[i][j] + m2[i][j];

}

}

return newM;

}

}

/*Körresultat :

mA :

0.0, 0.0

2.0, 4.0

5.0, 2.0

mB

1.0, 1.0

1.0, 1.0

1.0, 2.0

mA + mB

1.0, 1.0

3.0, 5.0

6.0, 4.0

*/

Hemuppgifter redovisning v41.

1. CBA-hemuppgift : Linjär-algebra-vektorer som arrayer.

Implementera i en klass Vect vektoralgebra i planet på liknade sätt som vi implementerade

algebra för komplexa tal på föreläsningen/i föreläsningsanteckningarna.

I klassen skall finnas definitioner för de statiska metoder som finns i detta diagram:

Namnen på metoderna i bilden är tagna från kapitel 3 i Linjär-algebra-boken.

IsEqual returnerar om två vektorer är är identiska, px returnerar vektorns x-komponent,

py returnerar vektorns y-komponent, scalarMultiple returnerar resultatet vi d multiplikation med skalär, dotProduct skalärprodukten, norm normen, sum summan av två vektorer,

difference skillnaden av två vektorer. mkVector "tillverkar" en vector, toString returnerar en sträng som vektorer i planet brukar skrivas i matteböcker, (x, y) .

Testkör klassen Vect med detta program (finns på /info/inda01/):

public class TestVector {

public static void main(String [] iargs) {

System.out.println(" (3, 4)= " +

Vect.toString(Vect.mkVector(3, 4)));

System.out.println(" (1, -2) + (7, 6) = " + Vect.toString(

Vect.sum(Vect.mkVector(1, -2),

Vect.mkVector(7, 6))));

System.out.println(" 3*(4,5) = " + Vect.toString(

Vect.scalarMultiple(3,

Vect.mkVector(4, 5))));

System.out.println(" ||(3, 4)|| = " +

Vect.norm(Vect.mkVector(3, 4)));

System.out.println(" (3, 4) o ( 2, 2) = " +

Vect.dotProduct(Vect.mkVector(3, 4),

Vect.mkVector(2, 2)));

System.out.println(" xkomponeten i (3, 4) = " +

Vect.px(Vect.mkVector(3, 4)));

System.out.println(" ykomponeten i (3, 4) = " +

Vect.py(Vect.mkVector(3, 4)));

}

} // Körresultat : Se nästa sida!

/*Körresultat :

(3, 4)= (3.0, 4.0)

(1, -2) + (7, 6) = (8.0, 4.0)

3*(4,5) = (12.0, 15.0)

||(3, 4)|| = 5.0

(3, 4) o ( 2, 2) = 14.0

xkomponeten i (3, 4) = 3.0

ykomponeten i (3, 4) = 4.0

*/

Utöka också TestVector med fler uttryck som testar Vect.

2. C-hemuppgift :Tärningsstatisik.

Lös uppgift 7.15 sid 359 i DD. Det är OK att istället för en applet skriva en applikation som bara startar och gör 36 000 slag och använda System.out för utskrift.

Exempel på körresultat:

Program som kastar två tärningar 36000 gånger

och skriver statistik för tärningarnas summa

Täningarnas summa 2 : 1037

Täningarnas summa 3 : 1999

.. osv

Täningarnas summa 12 : 1045

3. BA-hemuppgift : Matrismultiplikation.

Skriv en applikation som kan skriva ut två matriser och deras produkt. De två matiserna initieras i main-programmmet (det vill säga ingen inmatning krävs vid körningen). Programmet skall innehålla en metod för matris-multiplikation

public static double [][] mult(double [][] m1, double [][] m2 )

och en metod för att skriva ut en matris.

Exempel på körresultat:

mA :

0.0, 2.0, 0.0

0.0, 2.0, 1.0

1.0, 3.0, 1.0

0.0, 0.0, 1.0

mB

1.0, 1.0

1.0, 1.0

1.0, 2.0

mA * mB

2.0, 2.0

3.0, 4.0

5.0, 6.0

1.0, 2.0

4. B-hemuppgift : Game of -life Implementera följande spel :

The Game-of -life, invented by J. H. Conway, takes place on an rectangular grid of cells, each of which can contain an organism. Each cell has eight neighbours, and we use

occ(int j, int j, int [] [] biotope)

to denote the number of cells adjacent to cell at row j column j that are occupied by an organism. The configuration opf a new generation of organisms is obtained from the previos generation by applying two simple rules.

a) An organisk in cell [i][j] survives to the next generation if 2 <= occ(i,j, oldbiotope) <= 3,

otherwise it dies.

b) An organism is born in un emty cell [i][j] if occ(i,j, oldbiotope) = 3, otherwise the cell remains empty.

Write a program that reads an inital configuration of occupied cells, calculatees a series of generation acording to the rules, and prints each configuration.

because all changes occur simultaneously, the program must maintain two copies of the configuration. Test your program with a seven-cell, U-shaped pattern.

Lösningen skall innehålla en klassmetod för att skriva ut "biotopen", en klassmetod för att givet en generation av biotopen räkna ut nästa generation, klass-metoden occ ovan och main-metoden. Exempl på körning av U-biotopen,, se nästa uppgift. Märk dock att för B-uppgiften krävs ingen inmatning, utan startbiotopen initieras i programmet.

5. A-hemuppgift : Game of -life med inmatning av startbiotop.

Samma uppgift som uppgift 4, men vid körningen skall startbiotopens storlek och startbiotopen matas in från tangentbordet:

Ge antalet rader i startbiotop : 6

Ge antalet kolonner i startbiotop : 6

Rad 1 :

Rad 2 : * *

Rad 3 : * *

Rad 4 : ***

Rad 5 :

Rad 6 :

* *

* *

***

Fortsätta ge 1 : 1

** **

* *

*

(forts nästa sid)

Fortsätta ge 1 : 1

** **

** **

*

Fortsätta ge 1 : 0

Tips: Följande program läser in de fem första tecknen från en rad från tangentbordet och skriver ut dessa tecken. Är raden för kort fylls den ut med '-':

import java.io.*;

public class Radinmatning {

static BufferedReader indata =

new BufferedReader(new InputStreamReader(System.in));

public static void main(String [] iargs) throws IOException {

char [] r = readRow();

System.out.print("Inläst rad : ");

for ( int i =0; i < r.length; i = i+1) {

System.out.print(r[i]);

}

System.out.println();

}

public static char [] readRow() throws IOException{

char [] result = new char [5];

System.out.print("Rad : ");

String row = indata.readLine();

int rowEnds = Math.min(row.length(), 5);

for (int j = 0; j <rowEnds; j = j+1) {

result [j] = row.charAt(j);

}

for (int j = rowEnds; j <5; j = j+1) {

result [j] = '-';

}

return result;

}

}