Poly. - Javapakke til behandling af polynomier



Relaterede dokumenter
Skriftlig eksamen i Datalogi

Skriftlig eksamen i Datalogi

University of Southern Denmark Syddansk Universitet. DM502 Forelæsning 2

Eksempel: Skat i år 2000

Skriftlig eksamen i Datalogi

University of Southern Denmark Syddansk Universitet. DM502 Forelæsning 3

BRP Tal. Om computer-repræsentation og -manipulation. Logaritmer

AAU, Programmering i Java Intern skriftlig prøve 18. maj 2007

Skriftlig eksamen i Datalogi

Vejledende løsninger

ALMINDELIGT ANVENDTE FUNKTIONER

DM507 Algoritmer og datastrukturer

Ugeseddel 4 1. marts - 8. marts

DM507 Algoritmer og datastrukturer

DM507 Algoritmer og datastrukturer

Kursus i OOP og Java. Kursus i Objektorienteret programmering i Java

π er irrationel Frank Nasser 10. december 2011

DM507 Algoritmer og datastrukturer

SWC eksamens-spørgsmål. Oversigt

Forelæsning Uge 4 Mandag

class Time { int hours, min; } } Time t1; // Erklær variabel af type Time class Time1 { public static void main(string[] args) { Time t1; t1.

dcomnet-nr. 8 Simpel aritmetik på maskinniveau Computere og Netværk (dcomnet)

Forelæsning Uge 2 Torsdag

DM507 Algoritmer og datastrukturer

Indhold. Maskinstruktur Kapitel 1. Assemblersprog Indledning Hop-instruktioner Input og output...

Repræsentation af tal

Kapitel 4 Løkker i C#

Om binære søgetræer i Java

DM507 Algoritmer og datastrukturer

3 Algebra. Faglige mål. Variable og brøker. Den distributive lov. Potenser og rødder

JavaScript. nedarvning.

DM507 Algoritmer og datastrukturer

DM01 DM Obl. Afl. Jacob Christiansen, , D12, Elias 18/ Side 1 af 11

Forelæsning Uge 4 Torsdag

Maple. Skærmbilledet. Vi starter med at se lidt nærmere på opstartsbilledet i Maple. Værktøjslinje til indtastningsområdet. Menulinje.

Studiepraktik. Thomas Bøgholm Mikkel Hansen Jacob Elefsen

Programmering for begyndere Lektion 2. Opsamling mm

DM507 Algoritmer og datastrukturer

Klasse 1.4 Michael Jokil

Forelæsning Uge 2 Mandag

Algoritmedesign med internetanvendelser ved Keld Helsgaun

Python programmering. Per Tøfting. MacFest

Sproget Six. Til brug i rapportopgaven på kurset Oversættere. Vinter Abstract

Oprids over grundforløbet i matematik

Løsning af møntproblemet

DM507 Algoritmer og datastrukturer

Løsning af simple Ligninger

DANMARKS TEKNISKE UNIVERSITET

Andreas Lauge V. Hansen klasse 3.3t Roskilde HTX

Datalogi OB, Efterår 2002 OH er, forelæsning 10/ Klasser og nedarvning

Forelæsning Uge 4 Mandag

Skriftlig Eksamen Algoritmer og Datastrukturer (dads)

Hvad er Objekter - Programmering

University of Southern Denmark Syddansk Universitet. DM502 Forelæsning 4

class subklasse-navn extends superklasse-navn { } NorwaySpruce har superklassen Spruce, som igen har superklassen Tree.

APPENDIX A INTRODUKTION TIL DERIVE

Grundlæggende Matematik

DRONNINGER (QUEENS) Opgave 1

IT opgave. Informationsteknologi B. Vejleder: Karl. Navn: Devran Kücükyildiz. Klasse: 2,4

Talregning. Aktivitet Emne Klassetrin Side. Indledning til VisiRegn ideer Oversigt over VisiRegn ideer 1-7 3

Tree klassen fra sidste forelæsning

Sproget Rascal (v. 2)

Fejlkorligerende køder Fejlkorrigerende koder

Matematiske kompetencer - hvad og hvorfor? DLF-Kursus Frederikshavn Eva Rønn UCC

Repræsentation af tal

//Udskriver System.out.println("Hej " + ditfornavn + " " + ditefternavn + "."); System.out.println("Du er " + dinalder + " aar gammel!

Med TI-89 / TI-92 Plus kan du også sammenligne eller manipulere binære tal bit for bit.

Abstrakte datatyper C#-version

DM507 Algoritmer og datastrukturer

Programmering C Eksamensprojekt. Lavet af Suayb Köse & Nikolaj Egholk Jakobsen

DM507 Algoritmer og datastrukturer

Algoritmeskabeloner: Sweep- og søgealgoritmer C#-version

Repræsentation af tal

Grundlæggende Programmering ITU, Efterår Skriftlig eksamen i Grundlæggende Programmering

Forelæsning Uge 4 Torsdag

Forelæsning Uge 2 Torsdag

Første del af rapporten består af et diagram, der viser, hvor mange point eleverne på landsplan fik i de enkelte opgaver.

Forelæsning Uge 4 Mandag

Dokumentation af programmering i Python 2.75

Software Construction 1 semester (SWC) Spørgsmål 1

Forelæsning Uge 2 Mandag

Aritmetiske Forelæsning Pr ogrammering operatorer tir 1999 sda præcedens september 1999 Logiske Sammenligningsoperatorer operatorer præcedens

Danmarks Tekniske Universitet

Skriftlig Eksamen Algoritmer og Datastrukturer (dads)

DM507 Algoritmer og datastrukturer

22 Hobe. Noter. PS1 -- Hobe. Binære hobe. Minimum-hob og maximum-hob. Den abstrakte datatype minimum-hob. Opbygning af hobe. Operationen siv-ned.

Forslag til løsning af Opgaver til afsnittet om de naturlige tal (side 80)

1 monotoni & funktionsanalyse

Sortering. Eksempel: De n tal i sorteret orden

Programmering 1999 KVL Side 5-4. Klassen Time: metoder. Metoder i objektet giver mulighed for at ændre tilstanden, eller kigge på tilstanden.

Test af It-komponent

Træer. Datastrukturer & Algoritmer, Datalogi C Forelæsning 9/

Søgetræer: Generel repræsentation af (sorterede) mængder og funktioner Databasesystemer...

DM502. Peter Schneider-Kamp

4. Snittets kædebrøksfremstilling og dets konvergenter

Introduktion til differentialregning 1. Jens Siegstad og Annegrethe Bak

Danmarks Tekniske Universitet

Polynomiumsbrøker og asymptoter

Transkript:

Poly - Javapakke til behandling af polynomier z 3 x y x 2 3 x -3 Skrevet af Susanne Nykjær Knudsen, John Thystrup Jensen, Jens Lykke Brandt, Troels C. Damgaard, Jacob W. Winther og Mikkel Bundgaard Vejleder: Jørgen Larsen Naturvidenskabelig Basisuddannelse 4. semester Forår 2 Roskilde UniversitetsCenter

Abstract Formålet med dette projekt er at udvikle en Javapakke, der udfører aritmetiske funktioner på polynomier og undersøger forholdet mellem datastruktur og problemløsning. Javapakken baserer sin interne repræsentation på en datastruktur foreslået af Donald E. Knuth. Denne træstruktur er blevet anvendt, selvom vi fandt visse begrænsninger under programudviklingen. Disse begrænsninger har vi analyseret, og i perspektiveringen har vi foreslået en forbedret datastruktur til repræsentation af polynomier. De aritmetiske funktioner, der er implementeret i pakken er addition, subtraktion, multiplikation, division, integration, differentiation, eksponentialisering og negering. Desuden er der lavet en parser for at tilbyde en bruger af pakken et enkelt brugerinterface, hvori der anvendes tekststrenge til repræsentation af polynomier. Derudover har vi inkluderet en grafisk udskrift af datastrukturen via HTML. Konklusionen er, at det er muligt at lave en korrekt fungerende Javapakke, som kan anvendes til polynomieregning. Ydermere konkluderes det, at udformningen af datastrukturen har en stor effekt på problemløsningen, da det i høj grad er datastrukturen, som sætter rammerne for disse løsninger. English Title: Java-package for polynomial handling. - -

Indholdsfortegnelse. Indledning... 5 2. Definition på et polynomium... 7 2.. Polynomium... 7 2.2. Led i polynomium... 7 3. Brugervejledning... 8 3.. Beskrivelse af metoderne... 9 4. Datastruktur... 4.. Beskrivelse af træstrukturen... 4.2. Variable og konstanter... 2 4.2.. Konstant... 2 4.2.2. Variable... 3 4.3. Traversering i strukturen... 5 4.3.. Isolering af ét led... 5 5. Design af programpakke... 6 6. Implementering af design i Java... 2 6.. Problemstillinger under implementering af brøker... 2 6.2. Beskrivelse af enkelte klasser... 2 6.2.. Klassen SuperToNode... 2 6.2.2. Klassen Node... 2 6.2.3. Klassen Konstant... 2 6.2.4. Klassen Variabel... 2 6.2.5. Klassen InternPolynomim... 2 6.2.6. Klassen Polynomium... 22 7. Parsing... 23 7.. Problemstilling... 23 7.2. Overvejelser... 23 7.3. Krav til syntaks... 23 7.4. Hvad skal vores algoritme kunne gøre... 23 7.4.. Parsing af simple udtryk... 23 7.4.2. Parsing af mere avancerede udtryk... 24 7.4.3. Matematiske udtryk, der indeholder parenteser... 24 7.4.4. Matematiske udtryk, der indeholder multiplikation... 24 7.5. Syntaksdiagrammer... 25 7.6. Fejlfinding... 26 7.7. Opsamling på parsing... 26 7.8. Fremtidige udvidelser af parsing... 26 8. Vigtige ikke-matematiske metoder i pakken.... 27 8.. Metoden checkchars()... 27 8... Formål... 27 8..2. Algoritmebeskrivelse... 27 8.2. Metoden copy()... 28 8.2.. Formål... 28 8.2.2. Algoritmebeskrivelse... 28 8.3. Metoden genererled()... 28 8.3.. Formål... 28 8.3.2. Algoritmebeskrivelse... 28 8.3.3. Anvendelsen af genererled()... 3 8.4. tostring()... 32 8.4.. Formål... 32 8.4.2. Algoritmebeskrivelse... 32 8.5. printtohtml()... 34 8.5.. Formål... 34 8.5.2. Algoritmebeskrivelse... 34 9. Matematiske Metoder... 35 9.. Metoden Addition()... 35 9... Formål... 35-2-

9..2. Algoritmebeskrivelse... 35 9..3. Knuths additionsalgoritme... 35 9.2. Metoden multiply()... 36 9.2.. Formål... 36 9.2.2. Algoritmebeskrivelse... 36 9.3. Division... 39 9.3.. Formål... 39 9.3.2. Forbehold... 39 9.3.3. Algoritmebeskrivelse... 39 9.4. Integration... 42 9.4.. Formål... 42 9.4.2. Algoritmebeskrivelse... 42 9.5. Differentiation... 44 9.5.. Formål... 44 9.5.2. Algoritmebeskrivelse... 44 9.6. Negate... 46 9.6.. Formål... 46 9.6.2. Algoritmebeskrivelse... 46 9.7. Subtract... 46 9.7.. Formål... 46 9.7.2. Algoritmebeskrivelse... 46 9.8. polyexp... 46 9.8.. Formål... 46 9.8.2. Algoritmebeskrivelse... 46. Afprøvning... 47.. Opstilling af ækvivalensklasser for ét polynomium... 47.2. Afprøvning af matematiske metoder... 5.3. Opsummering af afprøvningsresultater.... 52.4. Diskussion af afprøvning... 52. Analyse af datastrukturen... 53.. Datastrukturens begrænsninger... 53.2. Undersøgelse af problemstillingerne... 55.2.. Konklusion på analysen af datastrukturen... 55 2. Konklusion... 57 3. Perspektivering... 58 3.. Et udtømt videnskabeligt område?... 58 3.2. Idé til ændret datastruktur... 58 4. Litteraturliste:... 6 5. Bilag printtohtml eksempler... 6 6. Bilag 2 Afprøvningsresultat... 63-3-

Forord Udgangspunktet for dette projekt er en fælles interesse for repræsentation og løsning af problemstillinger ved datalogiske metoder. Ideen stammer fra et af mange projektforslag stillet af Keld Helsgaun på datalogis hjemmeside. Forslaget omhandler en implementering af en Java-pakke til behandling af polynomier. Keld Helsgaun nævner samtidig en reference til The Art of Computer Programming, Vol. skrevet af Donald E. Knuth. På et par sider præsenterer Knuth en datastruktur til repræsentation af et flerleddet polynomium med et vilkårligt antal variable og angiver desuden i pseudokode en algoritme, der kan addere to sådant repræsenterede polynomier. Vi fik indledende en håndsrækning af Keld Helsgaun, der trak et gammelt projekt, skrevet over netop denne ide, frem af gemmerne. Dette projekt En Simula-klasse til Polynomium manipulation (Langberg, Finn og Peter Nielsen, 983) gav os først og fremmest et overblik over de mange muligheder, der var for funktionaliteter i en sådan Java-pakke. Det primære fokus har gennem hele processen været rettet mod den strukturerede udvikling og implementering af selve algoritmerne på den valgte datastruktur. Dette fokus ses også tydeligt i den færdige rapport. Vi har desuden forsøgt, igennem hele forløbet at forholde os kritiske og analyserende i forhold til både datastruktur og algoritmedesign. Det har resulteret i et langt udviklingsforløb, men har også bidraget til større forståelse for de valg og begrænsninger, man kan støde ind i, i forbindelse med datalogisk analyse og modellering. Vi vil gerne takke følgende personer: Vores vejleder Jørgen Larsen for at hjælpe os på vej, selv om han ikke fik meget fra os at arbejde med i starten af forløbet. Henrik Legind Larsen for hjælp og ideer på flere kritiske tidspunkter i forløbet. Vores opponentgruppe for kritisk gennemlæsning og gode diskussioner. Keld Helsgaun for at inspirere til et lærerigt og udfordrende projekt. Sidst, men ikke mindst Finn Langberg og Peter Nielsen, hvis rapport også har givet os et indblik i, hvordan man kan dokumentere et datalogisk udviklingsprojekt. Se http://www.dat.ruc.dk/~keld/algoritmik_e99/projektforslag/projektforslag_e98.pdf - 4-

. Indledning Dette projekt handler først og fremmest om datalogisk modellering og samspillet mellem datastrukturer og de algoritmer, der virker på dem. Vi har valgt at undersøge dette eksemplarisk i forhold til en konkret matematisk problemstilling. Dvs. idéen er, via udviklingen af funktionelt program, at lade dette understøtte en undersøgelse og analyse af en række datalogiske problemstillinger. Vi har i projektforløbet bl.a. stødt ind i en konkret problemstilling, der satte fokus på specielt de afgrænsninger, en defineret datastruktur kan give på problemløsning i forhold til den konkrete situation. Anvendelsen af datalogiske metoder til løsning af en problemstilling kræver i første omgang en datalogisk repræsentation af problemstillingen. Dvs. valg af en datastruktur, der kan repræsentere de kritiske data. Dernæst følger udviklingen og implementeringen af algoritmer, der løser problemerne på den valgte datastruktur. Sidst kræves en oversættelse og en fortolkning af de løsninger, algoritmerne udformer, så en løsning på den oprindelige ( virkelige ) problemstilling opnås. Dvs. den løsning, der ligger i datastrukturen(e) efter programkørsel, skal præsenteres for brugeren - selvfølgelig på en form, der er umiddelbart forståelig i forhold til den referenceramme, problemstillingen udstikker. Vi har valgt et velkendt og umiddelbart enkelt matematisk problem; beregning af resultater af aritmetiske operationer med polynomier. Dette stemmer overens med vores ønsker om at fokusere på problemerne i det datalogiske domæne. For at en computer skal kunne arbejde med et polynomium, skal det oversættes til en repræsentation, som er nem for computeren at arbejde med. En tekststreng er i princippet den enkleste entydige repræsentation af et polynomium. Det er den repræsentation, vi mennesker normalt sætter lig med et polynomium (selv om man ikke kan sige, at en notation er lig det matematiske udtryk, den beskriver) Vi har set meget enkle løsninger baseret direkte på tekststrengs-formen. I første omgang mener vi simpelthen ikke, at denne repræsentation er datalogisk pæn, og den er dermed heller ikke hensigtsmæssig i forhold til vores overordnede formål at lære noget om datalogisk modellering og samspillet mellem datastrukturer og algoritmer! For os mennesker er det let at overskue og finde f.eks. to ens led, hvis koefficienter skal adderes i en polynomieaddition, hvilket ikke er tilfældet for en computer. En fornuftig repræsentation vil derfor forsøge, at skabe det overblik over polynomiet, der gør det muligt for den hurtigere at finde og fortolke de rette elementer. I en tekststreng vil det være nødvendigt at gennemløbe hele strukturen før man med sikkerhed kan sige noget om forekomsten af ensartede led. En repræsentation, som ofte er hensigtsmæssig for en computer, er et træ eller en hægtet liste. Begge disse repræsentationer har den fordel, at de er dynamiske. De har den fordel, fremfor f.eks. et statisk array, at hvis man har brug for at indsætte et element midt i datastrukturen under programkørsel, behøver man blot at ændre i et par referencer i stedet for at skulle flytte alle de resterende elementer et felt frem. Vi har også set et eksempel på anvendelsen af en cirkulær enkelt-hægtet liste som datastruktur. Denne datastruktur havde det problem, at nok var den dynamisk mht. tilføjelsen af flere led, men den var ikke dynamisk i forhold til tilføjelsen af nye variable. Den krævede en eksplicit angivelse af de benyttede variable. Vi har i dette projekt valgt en datastruktur skitseret af Donald E. Knuth fra Stanford University. Denne datastruktur er beskrevet i hans bog The Art of Computer Programming (knuth 973), og tilføjer denne fleksibilitet mht. antallet af variable. Denne datastruktur er, som vi vil komme nærmere ind på i afsnittet Datastruktur, på en måde en sammenbygning af de to ovennævnte repræsentationsformer træer og hægtede lister. Den datastruktur, vi har valgt til repræsentation af et polynomium er rig i den forstand, at den er specialiseret til problemet, og vi mener, at den fanger de essentielle træk i forhold til problemstillingen. Vi har med andre ord valgt denne fremfor en række mere simple, der for det første kunne være for simple i forhold til vores overordnede mål om, at løse problemstillingen datalogisk smukt, og for det andet kunne lægge begrænsninger på datastrukturens dynamik. Vi har valgt, at arbejde med sproget Java, der er det sprog vi primært kommer til at anvende på overbygningen på Datalogi på RUC. Desuden tilbyder det en enkel måde, at distribuere kode på - som en Javapakke, der i princippet er en samling metoder, der kan anvendes i andre programmer med det interface, der tilbydes, uden at skulle bekymre sig om, hvordan funktionaliteten inden i pakken er. For at indpakke den datalogiske problemløsning i forhold til en programmør, der ønsker at bruge pakken (og i tråd med god objektorienteret tankegang), har vi desuden valgt, at lade den interne repræsentation være skjult inde i en pakke, der tilbyder et letforståeligt interface at arbejde med. Helt enkelt har vi valgt, at input og output skal være i form af tekststrenge. - 5-

Vi vil løbende forsøge at dokumentere og begrunde de valg, vi tager i design og implementering, og vi har valgt i et separat analyse-afsnit, med udgangspunkt i ønsket om at udvide problemstillingen til også at medtage negative eksponenter, at diskutere Knuths datastruktur og de begrænsninger selv denne rige datastruktur medfører. Dette leder frem til en problemformulering, som lyder - Problemformulering Med udgangspunkt i den valgte datastruktur, ønsker vi at udvikle en Java pakke til matematiske manipulationer med polynomier. Dermed ønskes følgende problemstillinger løst: - Implementering af datastrukturen - Udvikling/implementering af algoritmer, som udfører aritmetiske operationer baseret på denne datastruktur Endvidere ønskes pakken anvendt med tekststrenge og til dette formål skal følgende problemer løses - Udvikling af en algoritme, som parser en tekststreng til datastrukturen - Udvikling af en algoritme, som udskriver et polynomium som tekststreng. Vi vil desuden udfra en konkret problemstilling, der som nævnt gav fokus til de afgrænsninger en defineret datastruktur kan give på problemløsning, vurdere den valgte datastruktur som repræsentationsform for polynomier og give et bud på, hvordan den opståede problemstilling kunne afhjælpes ved at modificere datastrukturen. Målgruppe Projektets målgruppe er i første omgang dataloger og matematikere med interesse for samspillet mellem datastrukturer og algoritmer. Projektet anvender i udstrakt grad datalogisk terminologi specielt indenfor softwareudvikling. Det er en fordel at have programmeringserfaring i objektorienterede sprog. Rapportens opbygning Vi starter i rapporten med give en matematisk definition på et polynomium. I den efterfølgende brugervejledning gives et overblik over pakkens funktionaliteter. Dette afsnit håber vi både kan fungere som en hjælp til en programmør, der ønsker at anvende vores pakke, og derudover som et indledende overblik over de metoder, der senere vil blive gennemgået grundigere i metodebeskrivelserne. Inden metodebeskrivelserne er der en grundig gennemgang af den datastruktur, som vi anvender til intern repræsentation af et polynomium. Herefter følger afsnit om designet af Javapakken og den senere implementering af denne datastruktur i Java. I metodebeskrivelserne starter vi med at beskrive parsingen af tekststrenge til polynomier efterfulgt af de ikkematematiske metoder i pakken. Vi anvender både i dette afsnit og i det følgende om de matematiske metoder flowcharts og kodeudsnit som forklarende værktøjer. I det efterfølgende afprøvningsafsnit forsøger vi med systematiske tests (der er vedlagt i Bilag 2 Afprøvningsresultat at afprøve pakkens funktionalitet, og i afsnittet Analyse af datastrukturen præsenterer vi en række overvejelser omkring datastrukturen og dens begrænsninger. Vi viser i perspektiveringen et alternativt forslag til en datastruktur, som kan repræsentere polynomier. Vi har valgt, at vedlægge hele koden i en separat bilagsrapport så man har mulighed for at referere til denne under læsning af rapporten. Vi forestiller os, at det kan være hjælpsomt i at følge med i koden, ved læsning af flowcharts. Desuden er koden tilgængelig i digital form på http://akira.ruc.dk/~jlb/4. - 6-

2. Definition på et polynomium I dette afsnit vil vi give en kort matematisk definition på et polynomium. Denne definition er anvendt af Donald E. Knuth 2, og vi anvender den direkte som grundlag for vores program. Det skal dog bemærkes, at vi arbejder med rationelle koefficienter og heltalseksponenter > (det første er en udvidelse fra Knuth). 2.. Polynomium Vi definerer et polynomium af flere variable, som en sum af flere delpolynomier. Dette kan angives: g j j n x e j j Definition hvor x j er en variabel for j>. For j= er x j =. Det gælder ligeledes, at =e <e < <e n og at g j er et polynomium, der kun indeholder variable x,,x j- (g er altså en konstant). Desuden gælder det, at g,,g n er forskellig fra nul. De sidstnævnte regler "bøjes" lidt, da vi tillader, at man indtaster matematiske udtryk, der skal beregnes, som input til oprettelsen af et polynomium. Den ovennævnte definition angiver dermed den reducerede form, vi ønsker at vores Javapakke skal give som output til brugeren. Se Bilag 2 Afprøvningsresultat for eksempler på polynomier generet med denne definition. 2.2. Led i polynomium Som det fremgår af Definition kan man betragte et polynomium som summen af ét eller flere polynomier. Analogt til dette kan det enkelte led i et polynomium siges at være produktet af et eller flere polynomier bestående af enten en konstant eller en variabel opløftet i en potens. kx e e 2 2 x... x n e n Definition 2 Et led kan dermed have et af følgende formater: En konstant. En endelig række af variable, der alle er opløftet i en potens. En konstant ganget med en endelig række af variable, der alle er opløftet i en potens. 2 Knuth The Art of computer programming s. 357-7-

3. Brugervejledning Følgende afsnit har til formål at give en bruger en oversigt over vores Java-pakke. Dette afsnit omhandler altså kun pakkens interface og brugen heraf. Når brugeren skal bruge vores javapakke er der to ting, som han skal gøre. Importere pakken med import-sætningen for at få adgang til pakkens faciliteter og erklære de enkelte polynomier med new-sætningen. Når dette er sket har brugeren adgang til polynomierne og alle deres tilhørende metoder. De enkelte metoder er: add(), multiply(), subtract(), integrate(), diff(), copy(), iscorrect(), negate(), polydiv(), polyexp(), polymod(), tostring(), printtohtml(). Alle metoder, der modtager et polynomium kan kaldes men enten en reference til et polynomium, eller en tekststreng der angiver et polynomium. Et eksempel på brug af pakken kan ses nedenstående: import Poly.*; public class TestAfPoly { public static void main ( String args [] ){ Polynomium poly = new Polynomium( "2x^2+4" ); System.out.println( "poly: " + poly ); poly2.add( poly ); System.out.println( "poly2+poly: " + poly2 ); poly2.multiply("2xy^2+4x" ); System.out.println( "poly2*poly: " + poly2 ); Her er det brugeren, der selv opretter polynomierne. Her har han ikke brug for den fejlfinding, der ligger i pakken ved oprettelse af nye polynomier. Hvis brugeren derimod skulle lave en applikation, der tillod andre brugere at indtaste tekststrenge, der skulle laves om til polynomier, skulle disse jo testes om de overholdt syntaksen. Til dette bruges metoden iscorrect. Det skal her yderligere bemærkes, at bogstaverne æ,ø,å ikke er understøttet af pakken (dette er både som variabelnavn og som argument til integrate og diff) og at alle bogstaver bliver parset som små bogstaver. import Poly.*; import javax.swing.joptionpane; public class testafopretpolynomium { public static void main ( String args[] ) { String polyindtekst = JOptionPane.showInputDialog( "Indtast polynomium: " ); Polynomium indpoly = new Polynomium( polyindtekst ); // Bliver ved med at spørge efter et polynomium // indtil et korrekt er indtastet while (!( indpoly.iscorrect() ) ) { JOptionPane.showMessageDialog( null, "Polynomiet kan ikke oprettes med: " + polyindtekst ); polyindtekst = JOptionPane.showInputDialog( "Indtast polynomium: " ); indpoly = new Polynomium( polyindtekst ); JOptionPane.showMessageDialog( null, "Polynomiet er :" + indpoly ); Pakken er implementeret til at kunne tolke hele matematiske udtryk. Dette kunne f.eks. være udtryk som "((2.5xy^2+.6)*.5xy)^2", som den beregner under parsingen. Her ses det, at koefficienter også kan være negative og positive decimaltal. Som eksponenter modtages Integer-værdier. - 8-

Overholder et polynomium ikke den angivne syntaks, vil det under parsingen bliver sat til null. I pakken er der derfor indbygget en ekstra sikkerhed, der opdager metodekald med null som argument. Opdager en metode, at den bliver forsøgt kaldt med null udskriver den en fejlbesked og afsluttes. Ved et metodekald er det også muligt at det kaldende polynomium peger på null. Et metodekald med en reference, der peger på null, resulterer i, at Java kaster en NullPointerException, som kan fanges under programkørslen på følgende måde. import Poly.*; public class TestAfPolyVedFejl { public static void main ( String args [] ){ // poly overholder ikke syntaks og bliver under parsing sat til null Polynomium poly = new Polynomium( "2x^-2" ); Polynomium poly2 = new Polynomium( "2xy^2+4x" ); //forsøg addition til en refence, der peger på null try { poly.add( poly2 ); // fang NullPointerException og udskriv fejlbesked catch ( NullPointerException NPE ) { System.out.println( "Relevant fejlbesked" ); 3.. Beskrivelse af metoderne Vi vil i det følgende afsnit give en kort beskrivelse af de forskellige metoder, hvordan de kaldes og hvad de gør. Fælles for alle de metoder, der modtager et Polynomium 3 som argument, er at de også kan modtage en tekststreng, der så bliver parset til et Polynomium. Vi vil i eksemplerne bruge to polynomier: poly.add( poly2 ); poly.multiply( poly2 ); poly.subtract( poly2 ); poly.integrate('x'); poly.diff('x'); poly.copy( poly2 ); poly.iscorrect(); poly = 3x-2y^2 poly2 = 2x Metoden adderer de to polynomier og gemmer summen i poly. poly = 5x-2y^2 Metoden multiplicerer de to polynomier og gemmer produktet i poly. poly = 6x^2-4xy^2 Metoden subtraherer poly2 fra poly og gemmer differencen i poly. poly = x-2y^2 Metoden integrerer poly med hensyn til x, dvs. at den finder en stamfunktion til poly. Metoden tager som argument en char i intervallet [a;z], og gemmer resultatet i poly. poly =,5x^2-2xy^2 Metoden differentierer poly med hensyn til x, der som argument skal komme i form af en char i intervallet [a;z], og gemmer resultatet i poly. poly = 3 Metoden kopierer indholdet af poly2, hvis denne ikke er null, over i poly, der skal være oprettet på forhånd. Metoden returnerer true, hvis polynomiet er oprettet korrekt og false, hvis der opstod problemer under parsingen. 3 Her refereres der til klassen Polynomium - 9-

poly.negate(); poly.polydiv( poly2 ); poly.polymod( poly2 ); poly.polyexp(2); poly.tostring(); poly.printtohtml("c:\\test.html"); Metoden negerer poly. poly = -3x+2y^2 Metoden dividerer poly2 op i poly. poly indeholder derefter resultatet uden resten. poly2 må dog kun indeholde variable af en type i intervallet [a;z], men gerne flere led. Poly =. Metoden returnerer resten af divisionen af poly2 op i poly og gemmer resultatet i poly. poly2 må dog kun indeholde variable af en type i intervallet [a;z], men gerne flere led. poly = 3x-2y^2 Metoden opløfter poly i den potens angivet i argumentet som positivt heltal. poly = 9x^2+4y^4-2xy^2 Metoden udskriver poly som tekststreng. Metoden udskriver poly, som det ser ud på vores datastruktur. Den tager stien til udskriftsfilen som argument. I denne tekststreng skal det huskes at backslash i stien skal komme dobbelt pga. Javas måde at implementere specialtegn. - -

4. Datastruktur Dette afsnit redegør for, hvorledes et polynomium repræsenteres på den foreslåede datastruktur. Vi vil her give en dybtgående forklaring af dens opbygning, da den er udgangspunktet for resten af vores projekt. Da vi mange gange gennem rapporten anvender betegnelser omkring datastrukturen og dens egenskaber, vil vi nedenfor ligeledes forsøge at indføre den vigtigste nomenklatur. Man kan diskutere, hvordan datastrukturen skal betegnes. Knuth selv kalder den for et træ, og den har også mange ligheder med f.eks. et binært træ. Begge har de en rod, hvorunder der sidder noder, der så igen kan betragtes som en rødder i forhold til de underliggende noder. Den umiddelbare forskel på datastrukturen og klassiske træer er de cirkulære referencer, som træer normalt ikke indeholder. Strukturen er en kompleks hægtet liste. Den kunne nærmere opfattes som en quadro-hægtet liste, som måske ville være den betegnelse, der passer bedst. Men vi vil i det følgende afsnit bruge Knuths egen betegnelse og kalde strukturen for et træ. Bagerst i dette afsnit er en ordliste, hvor ord og begreber brugt i dette afsnit er opsummeret til hurtig reference. 4.. Beskrivelse af træstrukturen Grundbyggeklodsen i træstrukturen er noder, som vist i Fejl! Henvisningskilde ikke fundet.. Hver node indeholder seks felter. Up, Down, Left og Right er referencer til andre noder. EXP indeholder en heltalsværdi for eksponenten og CV værdien kan enten indeholde et tal eller en variabel (ét bogstav). Up EXP Right Left CV Down Figur : Node i datastruktur z 3 x y x 2 3 x -3 Figur 2 : Træ, der repræsenterer polynomiet : 3 + x 2 + xyz + z 3-3xz 3. Det indrammede område viser delpolynomiet 3 + x 2. Roden, den øverste node i træet, indeholder altid den alfabetisk største variabel i polynomiet, i dette tilfælde z. Roden er den eneste node i strukturen, hvis Left- og Right-referencer peger på sig selv. Desuden er eksponenten altid i roden (den bruges ikke!). - -

Som det fremgår af definitionen af et polynomium [Definition ], kan man betragte et polynomium, som summen af et antal mindre polynomier. De adderede polynomier kan på mindste plan bestå af produktet af en evt. konstant og et endeligt antal variable opløftet i en eksponent. I datastrukturen er dette afspejlet ved måden noderne er hægtet sammen på. En Up- eller Down-reference angiver, at to noder skal multipliceres sammen, mens en Right- eller Left-reference angiver, at de skal adderes. Et led bestående af multiplicerede noder kan derfor i strukturen aflæses ved at starte fra en node, hvis Down-reference peger på null, og følge Up-referencerne indtil denne peger på null, hvilket Up-referencen kun gør i roden af træet. Hver node, hvis Down-reference peger på null, angiver altså starten på et led, der skal adderes til resten af leddene. Eksponenterne for en CV-variabel kan læses af EXP-værdierne i det underlæggende niveaus noder. Eksponenterne er stigende, når man bevæger sig fra venstre mod højre i samme niveau i træet, og de må ikke være ens. Det er her vigtigt, at pointere at et niveau i træet refererer til noder hæftet cirkulært sammen og ikke nødvendigvis til grafisk sidestillede noder. Eksponenten er altid i noden, som en Down reference peger på, dvs. den node, som er placeret længst til venstre i et niveau. z x 3 2 Figur 3 : Udsnit af polynomiet i Figur 2 Polynomier kan betragtes som bestående af en række mindre polynomier. Figur 3, som er et udsnit af Figur 2, viser de to delpolynomier 3 og x 2. Dette læses ved at starte fra alle bundnoder (dvs. noder hvor Down-referencen er lig null) og følge Up-referencerne til roden. På Figur 3 starter konstant-polynomiet 3 i noden nederst, længst til venstre (på figuren markeret med gråt). I strukturen skal dette læses som 3. x. z. eksponenterne angiver jf. ovenstående eksponenterne for de ovenstående variable. Dette ses tydeligere i det andet delpolynomium x 2, der skal læses i strukturen som. x 2. z. 4.2. Variable og konstanter Et polynomium er, som tidligere beskrevet, defineret som summen af polynomier. Disse polynomier kan på mindste plan bestå af produktet af en evt. konstant og et endeligt antal variable opløftet i en eksponent. Dette betyder, at vi blot behøver at definere de to typer af træer, som repræsenterer henholdsvis en konstant og en variabel. Når vi kan oprette disse to typer, kan vi ved addition og multiplikation oprette alle andre polynomier. 4.2.. Konstant Som det fremgår af Figur 4, består en konstant af en node, hvis CV-værdi indeholder den talværdi, som den skal repræsentere og en Down-reference, som altid peger på null. - 2-

k Figur 4 : Konstant, repræsenteret ved en træstruktur I det tilfælde, hvor en konstant alene repræsenterer et polynomium, vil denne ligeledes være rod, og dens referencer sat i henhold til definitionen for denne, hvilket er angivet i Figur 5. En node, der indeholder en konstant, vil ofte blive refereret til som en konstantnode. De grå felter i figurerne er irrelevante i sammenhængen. Figur 5viser en konstant, der er rod. k Figur 5 : En konstant som rod 4.2.2. Variable Hvis polynomiet består af en variabel, skal der derimod altid være mindst 3 noder. Argumentationen for eksistensen af hver af disse tre noder kan findes i definitionen på træet. Som angivet i det ovenstående skal EXP-værdien for noden længst til venstre altid have værdien. Da opbygningen af datastrukturen ligeledes dikterer, at eksponenten for en variabel skal angives i det underlæggende niveau, er der behov for to noder på dette niveau, én med eksponenten nul og en, som indeholder eksponenten for variablen. x EXP Figur 6 : Variablen x EXP Da en variabel både kan have en eksponent og en koefficient, skal koefficienten naturligvis også kunne angives i træet. En koefficient kan betragtes som et konstantpolynomium, der er multipliceret på et variabelpolynomium. Som beskrevet tidligere er multiplikationer angivet ved Up- og Down-referencer samt, at de eneste betingelser en konstant skal opfylde er, at den indeholder en talværdi i CV, samt at dens Down reference peger på null. Grundet dette kan vi indsætte talværdien i den node under variablen, der indeholder eksponenten for variablen. - 3-

x EXP K Figur 7 : Variabel med koefficient Analogt til ovenstående kan vi udnytte, at Right- og Left-referencer angiver additionen af to led, når vi ønsker at addere en konstant til en variabel. Konstanten kan placeres i CV-værdien i noden længst til venstre, da den multiplikation som denne nodes Up-reference angiver, resulterer i konstanten selv. Vi har nu det mest komplekse polynomium som kan repræsenteres med tre noder. Følgende figur viser eksemplet : k x EXP2 + k 2. x EXP 2 K 2 K Figur 8 : Variabel med koefficient og adderet konstant Hvis k 2 faktisk er, refererer vi ofte til denne type noder som en nulnode eller en -node (refererer til, at både EXP og CV er ). Denne type node forekommer, jf. ovennævnte nomenklatur, kun længst til venstre i en række. En generel definitionen på repræsentation af en variabel med flere eksponenter, som er i overensstemmelse med definitionen, kan opskrives på følgende måde. x e e n... g g g n Figur 9 : Generel figur af udsnit af træstruktur, som repræsenterer en række i polynomium( Knuth, 973) Figur 9 viser et polynomium: g + g x e + g 2 x e2 +...+g n x en, hvor <e <e 2 <...<e n og g,., g n er polynomier med alfabetisk mindre variable end x. g, g n må ikke være nul, dermed følges den matematiske definition angivet ovenfor. Relevante observationer om datastrukturens definition er opsummeret her: - Den øverste node, kaldet træets rod, indeholder altid den alfabetisk største CV-værdi i polynomiet, og som den eneste node i strukturen peger dens Up-reference på null, mens Right og Left referencerne peger på noden selv. - Eksponenterne for en variabel er angivet af EXP-værdierne i det underlæggende niveau. - Eksponenterne er stigende, når man bevæger sig fra venstre mod højre på et niveau i træet. - 4-

- Eksponenten er altid i noden som en Down reference peger på, dvs. den node som er placeret længst til venstre på et niveau i en forgrening. - To eksponenter på samme niveau kan ikke være ens. - Polynomier kan betragtes som bestående af en række mindre polynomier. - Koefficienten i ét led af et polynomium er angivet i noden, findes ved at følge roots Down-referencer til bunden. 4.3. Traversering i strukturen For at kunne traversere rundt i strukturen er det nødvendigt med nogle stopbetingelser, der fortæller, hvor vi befinder os i strukturen. Udgangspunktet for en traversering af træstrukturen er givet ved opbygningen af strukturen og vil blive forklaret følgende. EXP-værdien i noden længst til venstre på et givent niveau er altid. Dette bliver anvendt som stopbetingelse i den vandrette traversering i et niveau i træet. Traversering foregår ved, at man går ned og til venstre - derved står man så langt til højre i et niveau som muligt. Ved derefter at traversere til venstre i niveauet vides det, at man har været hele niveauet igennem, når en node med EXP-værdien nås. En anden måde at kontrollere, om man står længst til venstre, er ved at gå Up og derefter Down. Da en Down-reference altid peger på noden længst til venstre i niveauet, kan vi ved en forespørgsel på, om noden vi står ved, bliver peget på af en Down-reference, konkludere om traverseringen skal afsluttes. Vi kan ved vandret traversering i strukturen finde relevante led ved at undersøge størrelsen af EXP-værdier, da det vides at EXP-værdierne er stigende fra venstre mod højre. Lodret traversering i strukturen benytter tre relevante stopbetingelser. Rodens Up-reference peger på null. Den alfanumeriske værdi bliver mindre når vi traverserer ned i niveauerne i et delpolynomium, og den nederste nodes Down-reference peger på null. Den fuldstændige traversering foregår naturligvis ved en kombination af lodret og vandret traversering, hvilket følgende vil forklare. 4.3.. Isolering af ét led I de algoritmer 4, der manipulerer træet, benyttes en metode, der har til formål at isolere et led. Da definitionen på en variabel dikterer, at dens Down-reference skal pege på en node med eksponent =, og et leds koefficient er angivet i den nederste node, kan man traversere ét led ved at gå ned og til venstre indtil en konstant nås. Fra denne node følges Upreferencerne indtil man står i roden. De fundne noder på vejen op i træet vil udgøre de multiplicerede dele af leddet (én konstant og antal variable). Ønskes det at finde det næste led i polynomiet, rykkes blot til venstre fra den sidst fundne konstantnode. Konstateres det, at man allerede står længst til venstre i et niveau (EXP = ), går man et niveau op og rykker til venstre og forsøger den nedadvendte traversering igen. På denne måde når man ned til alle konstantnoder og derved alle led i polynomiet. Et led kan derfor betragtes som værende på en slags trappestruktur, da de noder, som måtte være placeret til venstre for en node i leddet, kan betragtes som irrelevant, men for at bibeholde den strukturelle integritet skal en nulnode være placeret i hvert niveau. Dette princip vil blive anvendt i metoden genererled(), som er beskrevet i [8.3 Metoden genererled()] Afslutningsvis vil vi kort opsummere de mest relevante betegnelser præsenteret i afsnittet: Begreb Fuldt (repræsenteret) polynomium adderede led. "Længst til venstre" i en række i strukturen -node eller -led Forklaring Polynomium, der kan indeholde et vilkårligt antal Node, som en Down-reference peger på. Node, hvor både CV= og EXP= - forekommer kun længst til venstre i strukturen. 4 Additionen undtaget, da denne er udviklet af Knuth. - 5-

Rod Konstant polynomium Variabel polynomium Led Node øverst i strukturen Polynomium, der blot indeholder en konstantnode, der er rod. Polynomium, der indeholder tre noder, der tilsammen kun repræsenterer en variabel. En del af et fuldt repræsenteret polynomium. 5. Design af programpakke Følgende afsnit har til formål at beskrive den overordnede ide i programpakkens design. Udgangspunktet for denne beskrivelse vil være en række krav til programmet, som kan opstilles på baggrund af repræsentationen af polynomier, samt de krav, som skal opfyldes for at opnå den ønskede funktionalitet.. Træstrukturen skal bestå af noder som angivet i afsnit 4 Datastruktur 2. Der skal være mulighed for at oprette konstanter og variable. 3. Programmets funktionalitet skal implementeres, så den virker på både konstanter og variable, samt mere komplekse træer bestående af flere led. 4. Brugeren af programpakken skal ikke have adgang til den interne repræsentationsform, men blot anvende programpakken med tekststrenge. Designet, der opfylder disse krav, er angivet i følgende klassediagram (variable er angivet øverst, metoder nederst). - 6-

- 7-

- Node Up, Down, Left, Right - int EXP SuperToNode Node getup(), Node getdown() Node getleft(), Node getright() setup( Node U ), setdown( Node D ) setleft( Node L ), setright( Node R ) getexp() setexp( int EXP ), void abriviate() - Object CV - Integer CVNaevner, CVTaeller Node void setcv( Object cv ) Object getcv() void setcvnaevner( String BigIntInd) void setcvtaeller( String BigIntInd ) BigInteger getcvnaevner() BigInteger getcvtaeller() 3 Konstant - Node root Variabel void chainnode() void chainnodes() Node getroot().. *.. * - Node root - StringBuffer name InternPolynomium void add( InternPolynomium toadd ) void subtract( InternPolynomium tosubtract ) void multiply( InternPolynomium tomultiply ) void polydiv( InternPolynomium todivide ) void polymod( InternPolynomium todivide ) void copy( InternPolynomium tocopy ) void polyexp( int toexp ), void integrate ( char parttoint ) void diff( char parttodiff ) void negate() void printtohtml (String filnavn) String tostring() Node getroot() vigtige hjælpemetoder int checkchars( Node q, Node p ) genererled( InternPolynomium indpoly ) - InternPolynomium - Boolean iscorrect Polynomium void add( Polynomium toadd ) void subtract( Polynomium tosubtract ) void multiply( InternPolynomium tomultiply ) void polydiv( Polynomium todivide ) void polymod( Polynomium todivide ) void copy( Polynomium tocopy ) InternPolynomium pars( String strforste ) void polyexp( int toexp ) void integrate( char parttoint ) void diff( char parttodiff ) void negate() void printtohtml (String filnavn) String tostring() InternPolynomium getpoly() Boolean iscorrect() Figur : Klassediagram for javapakke Forklaringen vil tage sit udgangspunkt i den fundamentale enhed i træet - noden. Et polynomium er, som angivet i definitionen af denne Figur : Node i datastruktur, repræsenteret ved én eller flere af disse noder. Betragter vi - 8-

definitionen for noden, indeholder den fire variable med referencer til andre noder : Up, Down, Left, Right. Ligeledes indeholder den en variabel EXP, som ifølge definitionen indeholder et positivt heltal. Den sidste variabel, CV, kan enten indeholde et tal eller et bogstav. Grundet en bedre overskuelighed blev det besluttet, at eftersom CV er den eneste variabel som kræver typecheck, gav det god mening at oprette de metoder, som behandlede CV-variablen i en separat klasse. Dette gav et design, hvor en abstrakt superklasse SuperToNode indeholdt alle metoder, der ikke behandlede CVvariablen, mens subklassen Node indeholdt de metoder, som behandlede CV-variablen, som illustreret i ovenstående klassediagram. For at imødekomme computeres dårlige evne til at behandle rationelle tal, blev det besluttet, at når CV værdien bliver initialiseret som en talværdi, bliver to variable (CVNaevner og CVTaeller) tildelt heltalsværdier således, at de tilsammen repræsenterede CV ved en brøk. På denne må kunne vi anvende heltal, når vi ønskede at udføre aritmetiske operationer. Vi har nu det grundlæggende design, som muliggør sammenhægtning af noder, og det første krav er opfyldt. Det næste krav angiver muligheden for at oprette konstanter og variable. Som det fremgår af Figur er Konstant en subklasse af Node, hvilket giver god mening, da en konstant kan betragtes som et særtilfælde af denne. Konstant indeholder blot en metode chainnode(), som sætter referencerne som angivet i definitionen på en konstant når denne er rod. Som det fremgår af definitionen, indeholder Variabel tre noder. [4.2 Variable og konstanter]. Disse bliver oprettet, når en instans af Variabel bliver erklæret. Ligesom Konstant indeholder Variabel en metode chainnodes(), som sætter referencerne i noderne som angivet i definitionen for en variabel. Da en instans af Variabel indeholder flere Noder, benyttes en reference root, som peger på roden i træet. Denne variabel fungerer som indgang til den oprettede datastruktur. Vi har nu redegjort for, hvorledes designet opfylder de første to krav. Da både Konstant og Variabel består af noder, er det hensigtsmæssigt at anvende en klasse, der samler og anvender disse to klasser til at definere et helt polynomium. Når en instans af InternPolynomium bliver oprettet, undersøger den hvilken parameter, den er blevet erklæret med, og opretter enten en instans af Konstant eller af Variabel. Klassen InternPolynomium indeholder en variabel root, der sættes til at referere til enten Konstant-noden eller til roden i Variabel en, og der er nu adgang til træet igennem root variablen. Vi har nu et lag i designet, der gør det muligt at betragte både instanser af Konstant og Variabel som InternPolynomier. Vi har adgang til den underliggende træstruktur, hvilket muliggør implementeringen af algoritmer, der udfører matematiske metoder på strukturen. Disse metoder er derfor ligeledes implementeret i klassen InternPolynomium, hvilket opfylder det tredje krav. Det fjerde og sidste krav var, at brugeren af pakken ikke skal have adgang til den underliggende træstruktur, men blot anvende tekststrenge til at angive polynomier. Dette kræver, at endnu et lag bliver lagt på programpakken, som udgør pakkens interface udadtil. Klassen Polynomium indeholder ét InternPolynomium samt alle de metoder, der skal kunne udføres på et polynomium. Forskellen ligger i, at adgangen til metoderne i InternPolynomium er begrænset til programpakken, mens metoderne i Polynomium er offentligt tilgængelige for en bruger af pakken. Når disse metoder bliver kaldt på en instans af Polynomium, kalder Polynomium den tilsvarende metode for sit InternPolynomium. Polynomium indeholder ligeledes de metoder, som udfører parsingen af tekststrenge. Når Polynomium bliver erklæret med en tekststreng, kalder den parsingmetoden og gemmer resultatet i sit InternPolynomium. - 9-