Maple als programmeeromgeving

Print

De 'print' opdracht kan van pas komen om meldingen te geven aan de gebruiker of om fouten in programma's op te sporen. Om resultaten van berekeningen weer te geven kan men beter andere middelen gebruiken aangezien men geen verdere berekeningen kan doen met uitgeschreven resultaten. De syntax is zeer eenvoudig.

> print(`Hallo`);

Hallo

Strings worden in Maple aangeduid met forward quotes. Meerdere argumenten worden gescheiden door komma's en ook zo weergegeven.

> print(sqrt(3),sqrt(4));

3^(1/2), 2

Voorwaardelijke en herhalingsopdrachten

'if' opdracht

De implementatie van de 'if' opdracht lijkt nog het meest op die van Fortran.

> a := 4;

a := 4

> if a > 3 then
   a - 1

end if;

3

Merk op dat het de 'if' opdracht afgesloten wordt door 'fi'. Natuurlijk kan er ook een 'else' gedeelte toegevoegd worden en kunnen er meerdere statements uitgevoerd worden. Bovendien kunnen meerdere voorwaarden tegelijk getest worden mbv. Boolean operatoren 'and', 'or' en 'not'.

> if not((5 < a) and (a < 7)) then
   a := a - 1;

   a^2

else

   a := a + 1;

   sqrt(a)

end if;

a := 3

9

> a := 'a':

'if' statements kunnen genest worden mbv. 'elif'.

> Teken := proc(x)
   if x > 0 then

       printf("%d%s\n", x, " is positief")

   elif x < 0 then

       printf("%d%s\n", x, " is negatief")

   else

       printf("%d%s\n", x, " is nul")

   end if

end:

> Teken(-3);

-3 is negatief

> Teken(2);

2 is positief

> Teken(0);

0 is nul

> Teken := 'Teken':

'for' opdracht

De 'for' opdracht in Maple lijkt erg op die van BASIC:

> a := 0;

a := 0

> for i from 1 to 5 do
   a := a + i

end do:

a;

15

Het is uiteraard ook mogelijk een andere stapgrootte dan 1 te specifieren

> for i from 5 to 1 by -2 do
   a := a - i

end do:

a;

6

Er kunnen meerdere statements in een 'for' opdracht uitgevoerd worden.

> for i from 1 to 5 do
   a := a - 1;

   print(a)

end do:

5

4

3

2

1

Opgelet: de variabele 'i' die voor de iteratie gebruikt werd is geen lokale variabele:

> i;

6

De 'for' opdracht bevat echter een impliciete toekenningsopdracht, zodat dit in de praktijk geen problemen oplevert.

> a := 'a': i := 'i':

'while' opdracht

Herhalingsopdrachten worden niet steeds een vast aantal maal uitgevoerd, maar vaak ook tot een bepaalde voorwaarde voldaan is. Hiertoe kan men de 'while' opdracht gebruiken.

> a := 1000.0;

a := 1000.0

> while a > 2.0 do
   print(a);

   a := sqrt(a)

end do:

1000.0

31.62277660

5.623413252

2.371373706

> a := 'a':

Opmerking: Strikt genomen heeft Maple V slechts een enkele iteratie-opdracht: 'do ... od'. Deze kan de vorm aannemen van een 'for' of een 'while' of zelfs een mengvorm van beide.

'break' opdracht

Soms kan het nuttig zijn een herhalingsopdracht af te breken wanneer zekere voorwaarden optreden. Het is echter gewoonlijk aan te bevelen een 'for' door een 'while' opdracht te vervangen of het voorwaarde-gedeelte van een  'while' opdracht aan te passen. Omwille van volledigheid zal het toch vermeld worden.

> a := 10;

a := 10

> while a > 1 do
   if evalf(sqrt(a)) > 2.0 then

       print(a,sqrt(a))

   else

       break

   end if;

   a := a - 1

end do:

10, 10^(1/2)

9, 3

8, 2*2^(1/2)

7, 7^(1/2)

6, 6^(1/2)

5, 5^(1/2)

Hieruit blijkt duidelijk dat het gedeelte van de iteratie voor 'a' van 3 tot 2 niet meer uitgevoerd wordt. Uiteraard kon dit beter geformuleerd worden als:

> a := 10;

a := 10

> while (a > 1) and (evalf(sqrt(a)) > 2.0) do
   print(a,sqrt(a));

   a := a - 1

end do:

10, 10^(1/2)

9, 3

8, 2*2^(1/2)

7, 7^(1/2)

6, 6^(1/2)

5, 5^(1/2)

> a := 'a':

Datatypes en datastructuren

Eenvoudige datatypes

Hoewel er tot nog toe weinig aandacht aan besteed werd heeft Maple net zoals programmeertalen zoals Pascal en Java een aantal datatypes.  Voor Maple is deze lijst zelf ongewoon lang.  Het is eenvoudig na te gaan wat het type van een expressie is met behulp van de functie 'whattype'.

> whattype(a/(b*x + c));

`*`

> whattype(3.17);

float

> whattype(a);

symbol

> whattype(3);

integer

Het lijkt echter logisch dat het getal drie niet enkel van het type 'integer' is, maar ook een 'realcons', nl. een constante met een reele waarde.  Om dit na te gaan kunnen we gebruik maken van de functie 'type'.

> type(3, realcons);

true

Het is ook mogelijk het type na te gaan van ingewikkelder uitdrukkingen, bijvoorbeeld:

> type(a^(-3), name^integer);

true

maar:

> type(a^(-3), name^posint);

false

Hoewel het uiteraard nuttig is de types die Maple gebruikt te kennen om de werking van het programma beter te begrijpen is het geen strikte noodzaak zoals bij de meer conventionele programmeertalen.

Sequences en lijsten

Een sequence is een reeks grootheden gescheiden door komma's.

> S := a, b, c;

S := a, b, c

Sequences kunnen op diverse manieren aangemaakt worden:

> 0$10;

0, 0, 0, 0, 0, 0, 0, 0, 0, 0

> seq(2**i, i=0..10);

1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024

Het gebeurt slechts zelden dat je in Maple sequences aanmaakt, maar ze vormen wel de basis voor het vaak gebruikte 'list' type.

Een van de veel gebruikte datatypes van Maple is de 'list'. Lijsten vormen ook de basis voor het werken met vectoren en matrices. Een lijst definieren is erg eenvoudig:

> L := [1, 2, 3, 4];

L := [1, 2, 3, 4]

Elementen van een lijst kunnen uiteraard opgevraagd worden:

> L[4];

4

> L[4] := 7;

L[4] := 7

> L;

[1, 2, 3, 7]

Deze methodes zijn wel wat omslachtig als het om lange lijsten gaat, het kan echter ook automatisch mbv. het 'seq' (sequence) commando:

> L := [seq(i^2, i=1..12)];

L := [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144]

Om op elk element van een lijst een commando uit te voeren kan 'map' gebruikt worden:

> map(sqrt, L);

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

De elementen van lijsten hoeven niet allemaal van hetzelfde type te zijn:

> L := [1, a, x -> x^3, [1, 2, 3]];

L := [1, a, proc (x) options operator, arrow; x^3 end proc, [1, 2, 3]]

> map(`whattype`, L);

[integer, symbol, procedure, list]

Meestal is dit niet zo nuttig, behalve in het geval van geneste lijsten: deze hoeven immers niet allemaal dezelfde lengte te hebben zodat data op een efficiente manier voorgesteld kan worden.

> T := [[a, b, c, d], [e, f, g], [h, i], [j]];

T := [[a, b, c, d], [e, f, g], [h, i], [j]]

Deze geneste lijst kan gezien worden als de representatie van de symmetrische matrix hieronder:

> S := Matrix([[a, b, c, d], [b, e, f, g], [c, f, h, i], [d, g, i, j]]);

S := Matrix([[a, b, c, d], [b, e, f, g], [c, f, h, i], [d, g, i, j]])

De datastruktuur 'S' heeft n^2 elementen, 'T' slechts n(n+1)/2 waarbij n het aantal rijen van de matrix voorstelt.  Voor grote waarden van n is dit verschil van groot belang: voor n = 100 zou 'S' 10000 elementen bevatten, tegenover 5050 voor 'T'.

Een datarepresentatie zoals 'T' is dan wel efficient, maar heeft als nadeel dat er moeilijk mee gewerkt kan worden.  Men moet immers steeds nagaan of de indices i, j elementen boven of onder de diagonaal voorstellen:

> T[1,2];

b

> T[2,1];

e

> L := 'L': S := 'S': T := 'T':

Verzamelingen

Naast sequences, lijsten en arrays bestaat het type 'set'.  Om een stelsel vergelijkingen op te lossen met de  functie 'solve' worden sets gebruikt.  Het resultaat is eveneens een set.

> solve({3*x - y = 4, -2*x + 7*y = 3}, {x, y});

{y = 17/19, x = 31/19}

Er kan echter ook met sets gerekend worden, hieronder enkele voorbeelden.

> A := {0, 2, 4, 8, 10}; B := {2, 3, 5, 7};

A := {0, 2, 4, 8, 10}

B := {2, 3, 5, 7}

> A union B;

{0, 2, 3, 4, 5, 7, 8, 10}

> A intersect B;

{2}

> A minus B;

{0, 4, 8, 10}

> A := 'A': B := 'B':

Tables

Maple's table is analoog aan de record datastruktuur die in zowat elke programmeertaal terug te vinden is (Pascal, C,...).

> Circle := table([
 xCoord = 5,

 yCoord = 6,

 radius = 2]);

Circle := TABLE([yCoord = 6, radius = 2, xCoord = 5])

De data-elementen kunnen eenvoudig met behulp van hun naam opgevraagd worden:

> Circle[xCoord];

5

> Circle[radius];

2

Een nieuw element toevoegen:

> Circle[color] := "red";

Circle[color] :=

> print(Circle);

TABLE([yCoord = 6, color =

Het verwijderen van een element lijkt  iets ingewikkelder:

> Circle[color] := evaln(Circle[color]);

Circle[color] := Circle[color]

> print(Circle);

TABLE([yCoord = 6, radius = 2, xCoord = 5])

Er zijn twee functies 'indices' en 'entries' gedefinieerd die respectievelijk de namen en de waarden van de elementen in de table als resultaat geven:

> indices(Circle);

[yCoord], [radius], [xCoord]

> entries(Circle);

[6], [2], [5]

> Circle := 'Circle':

Procedures