Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (4.68 MB, 485 trang )

8.2 FullForm: What the Kernel Sees

myCommand#x' myCommand

Out[3]=

g$x, y(

g

a$b$x, y(, c(

a

a#b'#c'

a#b'

Even the expression a[b][c] qualifies as a legitimate nested expression. The head is the nested

expression a[b].

Every non-atomic Mathematica expression has this form, a head followed by square brackets enclosing zero or more arguments.

That last statement should give you pause. Consider the expression 2 + a. It is not atomic (we saw

this in the second to last output above), so what is the head? Where are the square brackets? What

are the arguments? It does not appear to have the form head[arg1, arg2, …]. What gives?

In[4]:=

Out[4]=

Head#2 a'

Plus

What’s going on is that the internal or FullForm of this expression is not revealed when we type 2 +

a. These paltry three characters are parsed into the following before being sent to the kernel for

evaluation:

In[5]:=

2 a ss FullForm

Out[5]//FullForm=

Plus#2, a'

Ah, so this expression does have the form of a nested expression after all, and the head is indeed

Plus. Mathematica allows you to type 2 + a because you’re a human, and that’s what you’re used to

(this is called the infix form of the Plus command). In this and in dozens of other cases you are

permitted to create expressions that do not look like proper nested expressions. This flexibility is

granted simply to make your interactions with Mathematica more natural, and to make the typing as

simple as possible. But in each of these cases your input is parsed into a properly structured nested

expression before being sent to the kernel. It is crucial to understand this fact if you are to program

effectively in Mathematica. FullForm is a great tool for peeking under the hood to view the internal

form of any Mathematica expression. Here are some other examples (for each expression in the left

column we show its FullForm in the right column):

387

388

Programming

In[6]:=

Grid%Table%exp, FullForm$exp( ,

exp, 2 a, 2

a, a, 2 ^ a,

a , 2 s a, S, Æ, 2, a, B, aB, aBB, a##1'',

a && b, a «« b, a, a 2, a s. b, a ss. b, a m b, a b, a b, a b,

a ± Reals, a aa b, a '#x', Ã a#x'Å x!!), Dividers Gray) ss Quiet

Out[6]=

2a

Plus#2, a'

2a

Times#2, a'

a

Times#1, a'

2a

Power#2, a'

a

Power#a, Rational#1, 2''

2

a

Times#2, Power#a, 1''

S

Pi

Ỉ

E

2, a

List#2, a'

B

Blank#'

aB

Pattern#a, Blank#''

aBB

Pattern$a, BlankSequence#'(

a317

Part#a, 1'

a && b

And#a, b'

a «« b

Or#a, b'

a

Not#a'

a2

Rule#a, 2'

a s. b

ReplaceAll#a, b'

a ss. b

ReplaceRepeated#a, b'

amb

Equal#a, b'

ab

Unequal#a, b'

ab

Less#a, b'

ab

LessEqual#a, b'

a ± Reals

Element#a, Reals'

a aa b

StringExpression#a, b'

a
#x'

Derivative#1'#a'#x'

¼ a#x'Å x

Integrate#a#x', x'

¿ Note that Quiet has been applied (in postfix form) in the previous input. This suppresses all

warning messages. In this case, for instance, the a /. b input generates a warning message that

b is neither a replacement rule nor a list of replacement rules.

8.2 FullForm: What the Kernel Sees

Note that FullForm can be subtle to use in some cases, as an expression may evaluate before Fullg

Form is applied. If one enters FullForm[a = b], for instance, the expression a = b evaluates and

returns b, and then the FullForm of b (which is simply b) is displayed. In fact, the FullForm of a = b

is Set[a, b]. In such cases, wrapping the expression in Defer will prevent this sort of premature

evaluation.

In[7]:=

FullForm#a

b'

Out[7]//FullForm=

b

In[8]:=

Out[8]=

In[9]:=

Out[9]=

Defer#FullForm#a

b''

Set#a, b'

Defer#FullForm#a : b''

SetDelayed#a, b'

Understanding the structure of the Mathematica language allows you to do many things. One clearly

sees at this point, for instance, the internal distinctions between the symbols =, :=, and m. They

correspond respectively to the commands Set, SetDelayed, and Equal. You will soon be able to

harness your knowledge of the structure of expressions to operate in interesting ways on complex

expressions. This is the essence of programming in Mathematica.

One last symbol deserves our attention in this context: the semicolon. We have used this symbol to

suppress output on many occasions. It also allows us to evaluate several commands in a single input

cell, like this:

In[10]:=

a

Out[10]=

6

3; 2a

The FullForm of the input above can be seen via Defer:

In[11]:=

Out[11]=

Defer#FullForm#a

3; 2a''

CompoundExpression #Set#a, 3', Times#2, a''

And here is the FullForm of an expression that ends in a semicolon:

In[12]:=

Out[12]=

Defer#FullForm#a

3;''

CompoundExpression #Set#a, 3', Null'

The command is CompoundExpression, and each argument is itself an expression. The arguments

are evaluated in turn, but only the output associated with the expression in the final argument is

displayed. CompoundExpression is an invaluable tool in writing Mathematica programs, for it

allows several inputs to be evaluated in turn, one after the other, with only the output of the last

input displayed.

389

390

Programming

Here’s one more example that may be revealing. Copy any graphic you like into an input cell, and

ask for its FullForm or InputForm to see its underlying structure. In this case we used the Drawing

Tools palette to create a simple image with the Line Segments tool.

ss FullForm

In[13]:=

Out[13]//FullForm=

Graphics$List#Line#List#List#0.21111111111111117`, 0.8333333333333334`',

List#0.2972222222222223`, 0.5972222222222223`',

List#0.18611111111111114`, 0.41666666666666674`',

List#0.31666666666666665`, 0.1972222222222222`''',

Line#List#List#0.5611111111111111`, 0.8361111111111111`',

List#0.4722222222222222`, 0.6027777777777779`',

List#0.5722222222222222`, 0.40000000000000013`',

List#0.4833333333333334`, 0.19999999999999996`''',

Line#List#List#0.7527777777777778`, 0.8305555555555556`',

List#0.8611111111111112`, 0.6222222222222222`',

List#0.7361111111111112`, 0.3944444444444444`',

List#0.8166666666666667`, 0.18055555555555558`'''',

Rule$PlotRange, List#List#0, 1', List#0, 1''((

¿ In fact, Mathematica notebooks are themselves valid nested expressions. If you were to open a

Mathematica notebook in a text editor, you would see a plain text file with the structure

Notebook[arg1, arg2, …]. The individual arguments in a notebook are cells, and every cell is

nested expression in its own right of the form Cell[arg1, arg2, …], and so on. This state of

affairs is most definitely intentional, and is even a little bit devious. It is devious in that the

FrontEnd does not reveal the highly structured nature of the underlying document, just as it

does not reveal the FullForm of expressions such as a , unless you ask for it. But underneath, the structure is there. The benefit (and a distinguishing feature of Mathematica) is that

you have access to this underlying form. Because cells and even entire notebooks have the

structure of a valid expression, it is possible to program Mathematica to operate on an entire

notebook. This was done, for example, in the writing of this book. Each chapter in this book is

a Mathematica notebook. The entire notebook expressions for all of the chapter files were sent

8.2 FullForm: What the Kernel Sees

to the kernel to programmatically generate the table of contents. They were sent again to

make the index, and so on. While the details of these specific techniques lie beyond the scope

of this book, it is important to understand the potential for operating programmatically on an

entire notebook.

Exercises 8.2

1. Find the Head of each of the following expressions:

a. x 2

b.

2

c. 1, 2, 3

d. Ó 1 &

2. Find the FullForm of each of the following expressions:

a. x 2

b. 1/2

c.

2

d. 1, 2, 3

3. What is the head of the expression a'[x]? Find its FullForm, and base your answer on what you

see. Check your answer with Head.

4. What is the FullForm of the expression 2x + 1 /. x 3? Use Defer and FullForm to find out.

5. What is the FullForm of the expression x = 3; 2x? Use Defer and FullForm to find out.

6. The command TreeForm produces a visual representation of the FullForm of any expression.

Find the TreeForm of the expression 2x + 1 /. x 3.

7. The Part command was introduced in Chapter 3 to extract a part of a list. It is typically invoked

via typing double square brackets. For instance the input {a, b, c}[[2]] will produce the output b.

But Part can also be used to extract parts of compound Mathematica expressions.

a. Apply TreeForm to the input a

b c

d2 .

b. Extract the zeroth, first, and second parts of this same input.

c. Find parts 32,17 and 32,27.

d. Find parts 32,2,17 and 32,2,27.

8. Go to the Graphics menu, create a new graphic, bring up the Drawing Tools palette, and draw an

arrow. Copy the arrow graphic into a new input cell, and apply TreeForm to the result.

9. A String in Mathematica is any collection of characters or symbols enclosed in double quotations.

Strings are atomic expressions. There are many commands available to operate on strings, but

one of the most basic is StringExpression. StringExpression[string1, string2] will concatenate the

391

392

Programming

two strings string1 and string2 into a single string. The infix form of StringExpression is ~~. That

is, one may invoke StringExpression by typing string1~~string2.

a. Type and enter a string. What do you see? What do you see if you apply FullForm to the

input?

b. Apply FullForm to the input "I am"~~" putting strings together."

c. Apply Defer to the input FullForm["a"~~"b"].

d. The command ToString will take any expression and convert it to a string. It is often used in

conjunction with StringExpression to create a string that depends on some external input.

Use ToString and StringExpression to create a command that will take a numerical input n

and return the string "n is my favorite number."

10. A notebook is comprised of cells. Each cell expression in a notebook has the head Cell. To see

the underlying form of a Cell expression requires a special technique, as the FrontEnd will

display Cell expressions nicely, that is, in a manner which hides the underlying structure of the

expression.

a. Click anywhere in any cell in any notebook, and in the menus go to Cell # ShowExpression.

The underlying cell structure will be revealed. In this state, you can edit it directly if you like.

Then toggle it back to normal with the same technique. Try this on several different cells in

one of your notebooks.

b. A Cell is a versatile structure, capable of many forms, from input to output to text to graphics.

So it may not be surprising to learn that Cell accepts a myriad of options. How many options

would you guess Cell can accept? Test your answer using the Options command.

8.3 Numbers

Types of Numbers: Integer, Rational, Real, and Complex

When working with a calculator or spreadsheet, one is typically not concerned with whether one

enters a whole number (such as 12) or a decimal number (such as 12.0). These are, after all, the same

number. In Mathematica, however, they are treated very differently, and for a good reason. Decimal

numbers are cursed with an inherent ambiguity stemming from the fact that while there are an

infinite number of decimal places, we cannot possibly write them all. There are two distinct

situations in which one would write a decimal number with finitely many places. In one, we write

such a number when we are rounding it, such as when writing S 3.14159. In the other, we agree to

stop writing decimal digits if beyond a certain point all the digits are known to be zero, such as when

writing 1 s 4 .25. Unfortunately, when one gives a computer a decimal number such as 3.14159 or

.25, there is no way for the computer to know which situation you are in. When you type .25,

should the computer interpret that to mean 1 s 4, or should it instead read it as the first two digits of

some potentially longer number, whose other decimal places are not known? Mathematica chooses

the latter: it treats all decimal numbers as approximations, where only the given decimal digits are

known, and where all additional decimal digits are treated as unknown. Mathematica refers to such

numbers as Real numbers.

8.3 Numbers

By contrast, an Integer, or whole number, is exact. There is no ambiguity. Likewise, fractions with

integer numerator and denominator are also exact. Such fractions are called Rational numbers.

While any kind of number is an atomic expression in Mathematica, the Head command (introduced

in the last section) can be used to identify the type of any number.

In[1]:=

Out[1]=

In[2]:=

Out[2]=

In[3]:=

Out[3]=

Head#12.0'

Real

Head#12'

Integer

Head#12 s 7'

Rational

It is often a shock for new Mathematica users to encounter output such as the following:

22

In[4]:=

7

22

Out[4]=

7

Mathematica simply will not convert an Integer or Rational number to a Real unless instructed to

do so. In cases where you seek a decimal output, either enter at least one Real number in the input,

or use the N command to convert it for you. Note that typing 22. is the same as writing 22.0.

22.

In[5]:=

Out[5]=

7

3.14286

22

In[6]:=

Out[6]=

7

ss N

3.14286

In addition to Integer, Rational, and Real numbers, there are also complex numbers, such as 2+3Ç,

where Ç represents the square root of 1. Regardless of which type of numbers comprise the individual real and imaginary components of such a number, Mathematica treats the entire expression as a

Complex number.

In[7]:=

Out[7]=

Head#2 3Ç'

Complex

393

394

Programming

In[8]:=

Out[8]=

Head#2.0 3.0Ç'

Complex

Displaying Numbers

It is important to understand that while real (decimal) numbers are displayed with six significant

digits, internally they are stored to at least machine precision (usually 16 significant digits). Perhaps

you have already discovered this; if you copy a real number from an output cell and then paste it

into a new input cell you will see the “full” machine representation of the number. Alternately, you

can use the command InputForm to display all the digits of a real number.

In[9]:=

N#S'

Out[9]=

3.14159

In[10]:=

N#S' ss InputForm

Out[10]//InputForm=

3.141592653589793

Note Mathematica’s InputForm for scientific notation:

In[11]:=

N$S

1020( ss InputForm

Out[11]//InputForm=

3.1415926535897933*^20

It is possible to display all the digits of a real number in any format you can imagine. While

Mathematica’s InputForm is handy for peeking under the hood, a more practical command for

displaying numbers is NumberForm. Here, for example, we see the first 12 digits of S (including the

digit to the left of the decimal point).

In[12]:=

NumberForm#N#S', 12'

Out[12]//NumberForm=

3.14159265359

This is not too exciting, as it looks like the output for N[S,12]. However, if the second argument to

NumberForm is a list of two positive integers, the first number specifies the total number of digits to

be displayed and the second specifies the number of digits to the right of the decimal. This can be

very useful. Here we see the first ten decimal places of S (compare the output carefully with the

output above; NumberForm displays the number rounded to the correct number of specified digits):

In[13]:=

NumberForm#N#S', 11, 10'

Out[13]//NumberForm=

3.1415926536

8.3 Numbers

If you ask for more total digits than needed, they will not be displayed.

In[14]:=

NumberForm#1.0, 10, 5'

Out[14]//NumberForm=

1.00000

However the option NumberPadding allows you to specify characters to pad the areas to the left

and right of the displayed digits.

In[15]:=

NumberForm$1.0, 10, 5, NumberPadding "ặ", "0"(

Out[15]//NumberForm=

ầầầầầ1.00000

The padding on the left in the output above appears to have one extra character; this is the space

reserved for the sign character in the case of negative numbers:

In[16]:=

NumberForm$1.0, 10, 5, NumberPadding "ặ", "0"(

Out[16]//NumberForm=

ầầầầ1.00000

A similar command is PaddedForm, which works essentially the same way as NumberForm, but it

will also “pad” the number with white space on the left, leaving room to accommodate all the

requested digits (and the sign character). Using PaddedForm will often free you from having to add

a NumberPadding option to NumberForm.

In[17]:=

NumberForm#1.0, 10, 5'

NumberForm$1.0, 10, 5, NumberPadding " ", "0"(

PaddedForm#1.0, 10, 5'

Out[17]//NumberForm=

1.00000

Out[18]//NumberForm=

1.00000

Out[19]//PaddedForm=

1.00000

PaddedForm is useful for displaying numbers in a table so that numbers in a column are all displayed with the same number of places to the right of the decimal, and with decimal points aligned.

395

396

Programming

In[20]:=

Out[20]=

Table#n, PaddedForm#N#n

S', 5, 2', n, 0, 6' ss Grid

0

0.00

1

3.14

2

6.28

3

9.42

4

12.57

5

15.71

6

18.85

Numbers that are very small or very large, however, will disturb the neat display above. Such numbers will (sensibly enough) be displayed in scientific notation (with the requested 2 places shown to

the right of the decimal):

In[21]:=

PaddedForm#.000001234, 12, 2'

Out[21]//PaddedForm=

1.23 106

In[22]:=

PaddedForm#1 001 234.5678, 12, 2'

Out[22]//PaddedForm=

1.00 106

If you do not want such numbers represented in scientific notation (for instance, if you are displaying monetary values and want your answer in dollars and cents), both NumberForm and Paddedg

Form accept the option setting ExponentFunction (Null&), which prohibits the display of

exponents.

In[23]:=

PaddedForm$.000001234, 12, 2, ExponentFunction +Null &/(

Out[23]//PaddedForm=

0.00

In[24]:=

PaddedForm$1 001 234.5678, 12, 2, ExponentFunction +Null &/(

Out[24]//PaddedForm=

1001234.57

This mechanism provides a sensible means of representing quantities such as money, where precisely two decimal places should be displayed. The following command could be used whenever a

monetary value x is to be shown. This particular implementation allows for at most ten digits to the

left of the decimal (so don’t use it to display the national debt).

In[25]:=

Clear#dollar';

dollar#xB' : PaddedForm$N#x', 12, 2, ExponentFunction +Null &/(

8.3 Numbers

In[27]:=

dollar#0.0049', dollar#0.0050', dollar#S', dollar$109 S( ss Column

0.00

0.01

Out[27]=

3.14

3141592653.59

Suppose you have one dollar, and it loses 1 s 3 of its value each year. Here’s what happens to your

dollar over time. The second column shows the numerical value to the default six significant digits,

while the third column displays this same value rounded to the nearest penny:

In[28]:=

Grid$Table$n, N$+2 s 3/n (, dollar$+2 s 3/n ( , n, 0, 15(,

Alignment ".", Dividers Gray(

Out[28]=

0 1.

1.00

1 0.666667

0.67

2 0.444444

0.44

3 0.296296

0.30

4 0.197531

0.20

5 0.131687

0.13

6 0.0877915

0.09

7 0.0585277

0.06

8 0.0390184

0.04

9 0.0260123

0.03

10 0.0173415

0.02

11 0.011561

0.01

12 0.00770735

0.01

13 0.00513823

0.01

14 0.00342549

0.00

15 0.00228366

0.00

More complex structures such as loan amortization tables can be built in a similar fashion.

If the number we wish to display is an exact integer (no decimal point) we need not specify digits of

precision, and scientific notation will not be used.

In[29]:=

NumberForm$1030 (

Out[29]//NumberForm=

1000000000000000000000000000000

But very large numbers are easier for humans to read if the digits are blocked in, say, groups of three.

NumberForm and PaddedForm have an option called DigitBlock to allow for this sort of display.

397

Tải bản đầy đủ (.pdf) (485 trang)