Sunday, June 30, 2013

My 1985 Notes on Wolfram's Harvard Talk on SMP - Precursor to Mathematica Part 2

Continuing from pp 1 - 3. This part contains some juicy tidbits that show how the principles underlying Wolfram's vision of a mathematical computer language have guided Mathematica's development to this day.

  

SMP contains the core of mathematical knowledge. A library of external files extends knowledge and gives definitions for particular applications; currently about 400 files.

Has a simple algorithm to strip to word roots and search a keyword index.

"This is a language, not something that thinks, and it was designed to be easy to tell things to it."

Dimensional analysis for physical units; fundamental units and derived terms' units.

Euler circuit in a graph (?)

Laplacian and divergences computed in various types of coordinate systems.

Routine mathematics should become as computerized as arithmetic.

SMP will run on a new generation of PCs.

One can typically define a hierarchy of types of objects. Then coerce two types to a common ancestor on a graph of types. How to get to the common ancestor? There may not be a unique path, so need a weighting function to [add efficacy to the search].

Vectorize: adds arrays of numbers in same number of operations as adding single numbers.

When to swap data with disc is left to the operating system. SMP needs a C compiler to work.

Gamma matrix manipulation.

Saturday, June 22, 2013

Non-Q Predicates in Mathematica

There are Predicates that are not given the Q suffix, which is an inconsistency in the nomenclature.

Numerical Non-Q Predicates

Less
Greater
Positive
Negative
Divisible
DiscreteDelta
KroneckerDelta

String Non-Q Predicates

NumberString
DigitCharacter
LetterCharacter
WordCharacter
WordBoundary
HexadecimalCharacter
WhitespaceCharacter
StartOfLine
EndOfLine
StartOfString
EndOfString

Monday, June 17, 2013

ApplyAll Applies a Function to all Subexpressions at Level One

ApplyAll

Instead of applying a function f to an entire expression, i.e. replacing the Head of the expression with f, use ApplyAll like Map to apply the function to each subexpression at level 1 of the expression. Apply defaults to Level 0 (the Head) and ApplyAll is just a convenient shorthand for Apply[ f, expr, 1].

Here is a typical example of ApplyAll. You have a List of number pairs and you want to perform some arithmetical operation such as add, multiply, divide, raise one to the power of the other, etc. (To remember the syntax of RandomReal I think of its arguments sequentially in English: "give me random reals between 1 and 20, 10 of them with length 2" (i.e. a 10 x 2 array).)

pairs=RandomReal[{0,1},{20,2}]

{{0.00994214,0.0701189},{0.024718,0.24013},{0.434799,0.996965},{0.323499,0.444366},{0.799502,0.843786},{0.964146,0.254526},{0.438815,0.943254},{0.228569,0.00348145},{0.247675,0.773157},{0.879202,0.615889},{0.898872,0.232664},{0.381568,0.75334},{0.464207,0.659948},{0.843115,0.179364},{0.287139,0.636774},{0.922514,0.193705},{0.969753,0.273868},{0.012059,0.247027},{0.560162,0.962637},{0.0593815,0.331142}}

Map doesn't work. It essentially disappears because it has no effect on a List:

Plus[List[a,b]]

{a,b}

Plus/@pairs

{{0.00994214,0.0701189},{0.024718,0.24013},{0.434799,0.996965},{0.323499,0.444366},{0.799502,0.843786},{0.964146,0.254526},{0.438815,0.943254},{0.228569,0.00348145},{0.247675,0.773157},{0.879202,0.615889},{0.898872,0.232664},{0.381568,0.75334},{0.464207,0.659948},{0.843115,0.179364},{0.287139,0.636774},{0.922514,0.193705},{0.969753,0.273868},{0.012059,0.247027},{0.560162,0.962637},{0.0593815,0.331142}}

But ApplyAll works perfectly; we always use its abbreviated version:

Plus@@@pairs

{0.080061,0.264848,1.43176,0.767865,1.64329,1.21867,1.38207,0.23205,1.02083,1.49509,1.13154,1.13491,1.12416,1.02248,0.923913,1.11622,1.24362,0.259086,1.5228,0.390524}

Times@@@pairs

{0.000697132,0.00593553,0.43348,0.143752,0.674608,0.2454,0.413914,0.000795751,0.191491,0.541491,0.209135,0.287451,0.306352,0.151224,0.182842,0.178696,0.265585,0.00297889,0.539232,0.0196637}

Here is a another example of ApplyAll. I want to make a toy directed graph so I can explore the new graph functions that have superseded the Combinatorica package as of Version 8.

randomEdges=RandomInteger[{1,20},{10,2}]

{{16,5},{17,17},{10,10},{15,2},{9,8},{20,9},{19,7},{20,15},{8,20},{11,3}}

Now I want to convert the pairs of numbers into a directed graph with DirectedEdge. My first try fails, again because each subexpression is a List.

toyGraph=DirectedEdge/@randomEdges

{DirectedEdge[{16,5}],DirectedEdge[{17,17}],DirectedEdge[{10,10}],DirectedEdge[{15,2}],DirectedEdge[{9,8}],DirectedEdge[{20,9}],DirectedEdge[{19,7}],DirectedEdge[{20,15}],DirectedEdge[{8,20}],DirectedEdge[{11,3}]}

What I need is ApplyAll.

toyGraph=DirectedEdge@@@randomEdges




It is equivalent to Apply[ DirectedEdge, randomEdges, 1].

Apply[DirectedEdge,randomEdges,1]


Sunday, June 16, 2013

My 1985 Notes on Wolfram Harvard Talk on SMP - Precursor to Mathematica Part 1

Here is more Mathematicana to celebrate Mathematica's 25th Anniversary. Thanks to my friend and intellectual complement John Deming ('you might be interested in this'), I was present at the creation, at least to hear, with growing excitement as I sat in Aiken 101 at Harvard in 1985, one of Stephen's early talks on the Symbolic Manipulation Program, SMP, which became Mathematica. I have it on good authority that none other than Steve Jobs, marketing genius extraordinaire, came up with the name Mathematica when Stephen solicited outside suggestions.

So here are pp 1-3 of my notes transcribed and an image. I'm sure I misunderstood some of the talk, so if in doubt check the SMP Handbook, a fascinating bit of history itself. Regarding the note that SMP was "written in 120K lines of C" as of the date of the talk, in this period Stephen could write up to 1000 lines of C code in a day.



298(85)/3/11 15:30
Harvard, Aiken 101

Dr. S. Wolfram

Arithmetic, logarithms - now hardware is powerful enough to do math generally. We need a language. Needs to be general, interactive, extensible, efficient (able to do heavy duty problems), portable (able to run without change on many computers).

Intrinsic data types: numbers, arrays of numbers. But need types for higher level objects, too, algorithms for them, and symbolic manipulation of them. An intrinsic structure to deal with these.

SMP. Symbolic Manipulation Program, which I started 5 years ago. Now it's 120K lines of C code later. SMP contains the core of a fundamental mathematical language; plus programmability allowing definitions of new objects; graphics; and a [functions] library.

The basic objects are numbers; symbols such as "a", "Pi"; projections i.e. parts of objects; and lists to specify collections of objects. Assignment of symbols to "values". You specify specific values then add more general expressions or values to which the machine goes if the specific values do not apply.

Conditions: $a_ = (test) to say $a such that (test) is true.

[Handles] multigeneric functions such as the gamma function. [Piecewise functions? But I'm not sure I got this right-KWC]

$$x stands for sequence of expressions.

It's important to have well-defined rules for pattern-matching. [SMP] will pattern-match even when not asked to solve explicit mathematical functions.

:   immediate assignment
::  delayed assignment

[Uses?] the Frobenius method of series expansion of differential equations. Total differential equations. XDSol J Greif & SW [Caltech?] Oct 1981.

Euler-Mascheroni constant.

Hypergeometric functions are very difficult to evaluate. Often evaluates to yield no value. Factorization: [uses the] fastest code written (as opposed to Berlekamp's). Integration: Risch etc algorithms.

Canonical form used for simplification. Applies the chain rule to reduce and solve differential equations.

Manipulates expressions: as trees, graphically.

List Operations: APL + symbolic operations etc.

Lends itself to building up programs instinctively, because symbolic language, unlike numerical languages (C?)...

Strongly based on pattern-matching. explicit assignment of cases [i.e. piecewise functions] is more natural and better for mathematics than a series of if-then functions.

User can define input & output syntax

Code generation: Convert SMP to C or FORTRAN for numerical cases: compile & load code incorporated; and add intrinsic code to SMP.

Written in 120K lines of C, runs under UNIX, VMS, VM...

Multi-n-ary tree internal data structure
Memory management
sub-expression sharing mechanisms
compacting garbage collection
-> intermediate expressions > ~16Mb
Block transfer.

Pp 4-5 of the notes are here and contain some fascinating insights into the principles guiding Mathematica's development to this day and beyond.




What I Gave Stephen Wolfram On His 50th Birthday

To celebrate the 25th anniversary of Mathematica's release, I will post some Mathematicana. I'll explain this chart more fully later but here is a prĂ©cis. Stephen developed Mathematica in part so that he'd have a powerful tool with which to explore the targets of his curiosity. (And we benefit by having a powerful tool with which to explore the targets of our curiosity!) The principal result of his explorations is A New Kind of Science (NKS for short), during the writing of which,  thanks to Mathematica, he made "more discoveries than I ever thought possible" (NKS p 22).

Until recently the history of science and separately, mathematics, displayed the great theme of logical reductionism, by which I mean our success at reducing disparate phenomena to a relatively few postulates or axioms. Viz, physics, or mathematics. While Wolfram's key discovery was that a short sequence can generate unlimited complexity (NKS Ch 2) and while "short sequence" does imply reductionism, the unlimited complexity is anti-reductionistic. To expose the phenomena described by some short sequences we must compute them interminably. This chart, an attempt to place NKS in history, is what I gave Stephen on his birthday several years ago (click to enlarge).

Thales, Pythagoras, Eudoxus, Aristotle, Euclid, Riemann, Bolyai, Schweikart, Gauss, Lobachevsky, Hilbert, Godel, Turing, Chaitin, Wolfram

The "flowstream" term is from the lectures of Andrew J. Galambos, a great, but largely unsung, philosopher. When I mentioned the concept of an intellectual flowstream to my friend Dave Waltz, he pointed me to the fascinating work of Eugene Garfield, notably the Web of Science.

Saturday, June 1, 2013

How It Works: First, Last, Rest, Map, Apply, Nest, Fold

I adapted these functions from exercises in David Wagner's superb book, Power Programming in Mathematica, now out of print, recommended by MathGroup.

The first four are examples of an axiom of primitive and general recursive functions, projection (see Gray, p. 411), but also of selectors, functions used in a data structure to access data in a controlled way without altering the data itself (see Maeder).

myFirst@head_[first_,last___] := first

myLast@head_[most___,last_] := last

myMost@{most___, last_} := {most}
myMost@head_[most___,last_] := {most}

myRest@head_[first_,rest___] := {rest}

Here is how Apply works:

myApply[f_, head_@anything___] := f@anything
myApply[f_, anything_] := f@anything

Recursive Definitions for Map, Nest, Fold


Note the piecewise definitions and use of recursion for Map, Nest, and Fold, which work so elegantly. Before seeing Wagner's solutions I thought these functions must use a procedural-type of iteration and list decomposition.

myMap[f_,{a_,b___}]:= Join[{f@a},myMap[f,{b}] ]
myMap[f_,{}]:={}  (* base case *)

myNest[f_,x_,n_Integer?Positive]:= myNest[f,f@x,n-1]
myNest[f_,x_,0]:= x  (* base case *)

myFold[f_,x_,{a_,b___}]:= myFold[f,f[x,a],{b}]
myFold[f_,x_,{}]:= x  (* base case *)

Recursive, Rule-Based Definitions for Map, Nest, Fold


Here are Map, Nest, and Fold using a "pure" rule-based approach, meaning using only rules and patterns. Wagner notes that it turns out that Map is the most difficult of them to implement this way.

Clear[myNest,myFold,myMap];

myNest[f_,x_,n_Integer]:= {x,n}//.{{a_,0}:>a,{a_,b_}:>{f@a,b-1}}

myFold[f_,x_,s_List]:= {x,s}//.{{a_,{}}:>a,{a_,{b_,c___}}:>{f[a,b],{c}}}

myMap[f_,s_List]:= Module[{r},{s,{}}//.{{{},r_}:>r, {{a_,b___},r_}:>{{b},Append[r,f@a]}}]