• Aucun résultat trouvé

Block and Module

Dans le document Essentials of Mathematica (Page 71-77)

Essential Commands

1.19 Clear, Clear All, and Remove

1.21.1 Block and Module

The elaboration of a program is usually done in several steps, and intermedi-ate results have to be kept. The command Module [ v a r i a b l e s , expression]

is a very convenient construct to achieve this goal. One important feature of this structure is that v a r i a b l e s are treated as local when they appear in expression. Block [ v a r i a b l e s , expression] is a similar structure that, however, behaves differently in the way it handles variables as illustrated be-low.

Clear[x,

Replacing Block by Module yields Clear[x, y,

In Block, u is replaced by its expression sm{x)-\-cos^(y) and u-\-lis evaluated using the local values x = 7r/2 and y = n/A. In Module, because in li + 1 the symbols x and y do not appear explicitly, they are not replaced by their local values X = TT/2 and y = 7r/4, but when returning w + 1, Module replaces x by its value 7r/4 and leave y unevaluated since no value had been assigned to 2/- As shown above, variables can be assigned values inside the Block and Module structures.

The following example shows the local character of a variable value defined inside a Block.

Here is a more interesting example.

Block [{$DisplayFunction = I d e n t i t y } , p i = P l o t [Sin [ x ] , {x, 0, 2 P i } ] ; p2 = P l o t [ C o s [ x ] , X, 0, 2 P i ] ; ]

1.21 Programming 45 We already used DisplayFunction as an option for graphics functions that specifies the function to apply to graphics in order to display them. The local value I d e n t i t y for DisplayFunction suppresses the output to the screen. To see the output to the screen, we have to use Show.

Show[pi, p 2 ] ;

0 . 5

- 0 . 5

Fig. 1.9. Graphs of sin x and cosx for x G [0,27r].

If we did not use Block [ ] , we should have entered

p i = P l o t [ S i n [ x ] , {x, 0, 2 P i } , DisplayFunction -> I d e n t i t y ] ; p2 = P l o t [Cos [ x ] , {x, 0, 2 P i } , DisplayFunction -> I d e n t i t y ] ; and then used the option DisplayFunction -> $DisplayF\mction, which was not necessary when using Block because $DisplayFimction was a local variable. Because $DisplayFunction gives the default setting for the option DisplayFunction, the graphs are then displayed on the screen using the input:

Show[{pi, p 2 } , DisplayFunction -> $DisplayFunction];

The command Module has the same property. To see how to use it, it is prob-ably better to build up a simple program that exhibits its essential features.

In the section dedicated to hsts, we have obtained step by step the least-squares fit of data represented by a list, using a combination of functions.

Given a data list, the function d a t a F i t P l o t , defined below, groups all the

various steps together to find the best least-squares fit by a polynomial of degree n in an interval defined by its lower and upper bounds and to plot on the same graph the data points and the fitting curve.

d a t a F i t P l o t [data_List, degree_Integer, lowerBoundJleal, upperBoundJleal] : =

Module[{lisPl, powerList, f i t F u n c t i o n , f i t P l , x } , l i s P l = L i s t P l o t [ d a t a , DisplayFunction -> I d e n t i t y ] ; powerList = Table[x'^k, {k, 0, d e g r e e } ] ;

f i t F u n c t i o n = F i t [ d a t a , powerList, x] ;

f i t P l = P l o t [ f i t F u n c t i o n , {x, lowerBound, upperBound}, DisplayFunction -> I d e n t i t y ] ;

Show[{lisPl, f i t P l } , DisplayFunction -> $DisplayFunction]]

We can use this program to find the least-squares fit of a list of values of the cosine function including some noise in the interval [0, 27r].

C l e a r [ d a t a ]

d a t a = Table[{x, Cos[x] + 0 . 2 5 Random[]}, {x, 0, 2 P i , 0.2}]

{{0, 1.03372}, { 0 . 2 , 0.984004}, { 0 . 4 , 1.10815}, { 0 . 6 , 0.841229}, { 0 . 8 , 0.918472}, { 1 . , 0.642946}, { 1 . 2 , 0.378395}, { 1 . 4 , 0.254044}, { 1 . 6 , 0.0212607}, { 1 . 8 , -0.00621556}, { 2 . , -0.352155}, { 2 . 2 , -0.361068}, { 2 . 4 , -0.502693}, { 2 . 6 , -0.838658}, { 2 . 8 , -0.926133}, { 3 . , -0.774244}, { 3 . 2 , -0.943265}, { 3 . 4 , - 0 . 7 8 9 8 6 } , { 3 . 6 , -0.871707}, { 3 . 8 , -0.564668}, { 4 . , -0.445388}, { 4 . 2 , -0.463964}, { 4 . 4 , -0.127786}, { 4 . 6 , -0.0343247}, { 4 . 8 , 0.262035}, { 5 . , 0.306022}, { 5 . 2 , 0.710974}, { 5 . 4 , 0.696627}, { 5 . 6 , 0.978336}, { 5 . 8 , 1.05524}, { 6 . , 1.18659}, { 6 . 2 , 1.2244}}

Note that because we have chosen to represent the lowerBound and upperBound variables as real numbers, they should be written 0. and N [2Pi] and not sim-ply 0 and 2Pi.

1.21 Programming 47 Using the Module construct to define a function F of the variables x, y, . . . that needs to first determine an expression e l involving x, y, . . ., then an expression e2 involving e l and possibly x, y, . . . , we observe that we have to use a structure of the form F[x_, y_,. . .] := Module [ { e l , e 2 , . . . } , body] where in body are defined the intermediate expressions e l , e2, in terms of X, y, . . . , and previously defined expressions.

The definitions of each intermediate expression must end with a semicolon (;), and all intermediate expressions have to be listed in the first argument of the module. When defining the intermediate expressions, built-in functions or user-defined functions (previously defined) can be used. Note that there is no semicolon after the last command which represents the required final output.

d a t a P i t P l o t E d a t a , 3 , 0 . , N[2Pi]]

1 . 5

0 . 5

- 0 . 5

Fig. 1.10. Least-squares fit of the data above.

1.21.2 Collatz P r o b l e m

We first build up a few functions to study the so-called Collatz problem. Also known as the 3x + 1 problem, the Collatz problem is the following conjecture.

Starting from any positive integer n, if this integer is even, divide it by 2, if it is odd multiply it by 3, add 1 and then divide the result by 2. Iterating this pro-cess, the sequence of integers thus obtained falls into the cycle 1,2,1,2,1, For a very detailed review of the Collatz problem, consult Lagarias [29].

Mathematically, this means that the sequence of iterations of the Mathematica function:

C o l l a t z [n_?OddQ] := (3n + 1) / 2 Collatz[n_?EvenQ] := n / 2

falls into the cycle 1 , 2 , 1 , 2 , 1 , . . . .

Using an If statement we can also define the CoUatz function a bit differently by

C o l l a t z [ n _ I n t e g e r ? P o s i t i v e ] := I f [ E v e n q [ n ] , n / 2 , (3n + l ) / 2 ] The statement If [ c o n d i t i o n , t , f] gives t if condition evaluates to True, and f if it evaluates to False. Consider an example.

N e s t L i s t C C o l l a t z , 67, 25]

{67, 101, 152, 76, 38, 19, 29, 44, 22, 1 1 , 17, 26, 13, 20, 10, 5, 8, 4 , 2, 1, 2, 1, 2, 1, 2, 1}

Nest [f, express i o n , n] gives the result of applying f n times to expression.

N e s t L i s t [ f , e x p r e s s i o n , n] gives a list of the results of applying f to e x p r e s

-s i o n from 0 through n time-s.

If we define the length of a Collatz sequence as the smallest integer i such that the ith iterate equals 1, the following function may be used to determine this length.

CollatzSequenceLength [n_Integer] : = Module[{k = n, 1 = 1 } ,

WhileC k != 1, k = Collatz[k]; 1 = 1 + 1 ] ; 1]

CollatzSequenceLength[67]

20

CollatzSequenceLength [2''50 - 1]

384

We can also find the Collatz sequence as the sequence of iterates ending with the first iterate equal to 1.

1.21 Programming 49 CollatzSequence [ n _ I n t e g e r ? P o s i t i v e ] : =

Module [{nl = n, 1 = {n}},

While[ n l != 1, n l = C o l l a t z [ n l ] ; 1 = A p p e n d [ l , n l ] ] ; 1]

Append [ e x p r e s s i o n , element] gives e x p r e s s i o n with element appended.

CollatzSequence[45]

{45, 68, 34, 17, 26, 13, 20, 10, 5, 8, 4 , 2, 1}

CollatzSequence[1453]

{1453, 2180, 1090, 545, 818, 409, 614, 307, 461, 692, 346, 173, 260, 130, 65, 98, 49, 74, 37, 56, 28, 14, 7, 11, 17, 26, 13, 20, 10, 5, 8, 4, 2, 1}

We can test the Collatz conjecture on all integers between 1 and 10 000 000 with the following function. We verify that the tested list has actually the correct length.

CollatzSequenceLengthList =

Table[CollatzSequenceLength[k], {k, 1, 10000000}]; / / T i m i n g Length[CollatzSequenceLengthList]

{ll.0539Second, Null}

10000000

Dans le document Essentials of Mathematica (Page 71-77)

Documents relatifs