This site is supported by donations to The OEIS Foundation.

Style sheet for Mathematica programs

From OeisWiki
Jump to: navigation, search

Technically, the only requirement for a Mathematica program in the OEIS is that it provide the correct results.

However, over the years, certain conventions have evolved, both among OEIS contributors who use Mathematica as well as among the larger community of Mathematica users. It is perhaps useful to be aware of these conventions.

First, one should be aware that not everyone upgrades their software at each minor release or even each major release. While few still use Mathematica 1.0, many use version 6 or 7 and some could be using versions as old as 5.2. See list of number theoretic functions in Mathematica by version.

According to the Style Sheet, Mathematica-specific symbols shouldn't be used in the Name, Comment or Formula fields (because not everyone knows Mathematica). But they are of course entirely appropriate in the Mathematica field! Thus, E, GoldenRatio, ZetaZero[1] and StieltjesGamma[3] rather than , , "first zero of the Riemann zeta function" and "third Stieltjes constant," respectively.

In particular, the Name field should contain generally understood mathematical notation and not Mathematica commands. For example, RealDigits[Sqrt[E]] is not a valid name for A019774. A more appropriate name would be something like "Decimal expansion of the square root of e."

It needs to be emphasized that Mathematica programs in the OEIS need to give results. Something like this:

a[n_] := MoebiusMu[n] * someFunction[n - 1];

is incomplete even if someFunction is defined. Whether someone is new to Mathematica or has been using it for years, they should be able to simply copy and paste a Mathematica program from the OEIS, press Enter and get results.

Brevity

Whenever possible, Mathematica programs in the OEIS should be brief and use functions and constants built into the most recent version in widespread use. For example, these are perfectly acceptable programs to compute A000045 and A000142 respectively:

Table[Fibonacci[n], {n, 0, 38}]
Range[20]!

While these programs are getting a little bit too long for the purpose:

a[0] := 0; a[1] := 1; a[n_Integer] := a[n] = a[n - 2] + a[n - 1]; Table[a[n], {n, 0, 38}] (* Four statements *)
facl[0] := 1; (* Empty product *)
facl[n_Integer] := facl[n - 1] * n; (* Simple recursion *)
Table[facl[n], {n, 0, 19}] (* Three statements over three lines, but that's enough, I think *)

But a program like the first of these last two examples makes sense for lesser known recurrences, such as (see A022405). The second of these last two examples is actually over-commented. In general, Mathematica programs in the OEIS don't need any comments, at least not in the way comments are used in C++ source code for full-fledged applications like a photo editor, a spreadsheet, or Mathematica itself.

Signing programs

Comments should be used to "sign" programs not included in the original sequence:

Range[20]! (* From John Gonzalez, Jan 01 2000 *)

rather than

Range[20]! - [From John Gonzalez, Jan 01 2000]

This makes it easier to paste the program into a Mathematica notebook.

Since May 21, 2012, you can use (* ~~~~ *) in the OEIS Main sequence editing page to automatically add your name and date into a Mathematica comment. For example, if your are John Gonzalez and today is June 1, 2012, the following in a sequence editing page

Table[myFunction[n], {n, 100}] (* ~~~~ *)

will become

Table[myFunction[n], {n, 100}] (* John Gonzalez, Jun 01 2012 *)

after you click the "Save changes" button.

Naming conventions

Despite the need for brevity, it is also important to give functions and variables meaningful names, so that Mathematica users consulting the OEIS aren't let to the frustration of having to clear a whole bunch of symbols consisting of single letters, or quit and restart the kernel. For symbols of local scope, such as iterators, it's quite appropriate to use single letters, like n and k in our examples above.

But for functions and constants that other users can use again or clear at their option, longer, more meaningful names are needed. They don't have to be terribly long: instead of palindromicNumberQ, one can use palindromicQ or even palQ; these are much more informative than okQ or worse, pQ.

Noticing that all built-in functions, variables and constants in Mathematica start with uppercase letters, many Mathematica users have adopted the convention of only using lowercase letters to start off their own user-defined symbols. Neither Mathematica nor the OEIS enforce this, but observance of this guideline can help other users more easily distinguish between functions introduced in a version after the one they have and functions defined by other users.

In Mathematica, functions ending with an uppercase Q are usually (not always) Boolean functions that return True if the argument is described by the word before the Q, and False otherwise. Thus, PrimeQ[n] is True if n is a prime. This can also be observed in user-defined functions, such as semiPrimeQ or palindromicQ.

When a sequence requires a lengthier, more complicated program to calculate, it might be helpful to assign the entire output to a list named with the sequence's A-number:

A234567 = Module[{x = 0, y = 1, flag = False}, If[(GoldenRatio - x) etc., etc.

Then, programs in related sequences can simply refer to the A-number,

Select[A234567, EvenQ]

and thus not have to repeat the lengthy, complicated program.

Speed

Except for sequences with keyword:hard, the Mathematica program should return results quickly if not instantaneously. If it takes longer than a few seconds, there could be some inefficiency in the reasoning behind the computation, such as looking at all even integers in cases when only multiples of 32 need be considered.

Generally, it is better to give the sequence as a Mathematica list (that is, "{2, 3, 5, 7, 11, 13, 17, 19}") rather than using Print to give each term by itself on its own line,

2

3

5

7

11

13

17

19

making it easier for others to manipulate the list based on ideas that might occur to them upon seeing the results. However, for more difficult sequences, there is some merit to printing out each term as it is obtained, letting the user know that the program is working and that it hasn't gotten stuck in an infinite loop or crashed.

It is acceptable for a Mathematica program to give a few more terms than the sequence entry shows. For example, A000045 shows the first forty Fibonacci numbers or so, but there's nothing wrong with the program giving the first fifty. Too many beyond that is considered bad form, especially if it takes longer to get those extra terms.

Transparency of logic

With the above concerns satisfied, if it's also practical, the logic of the program should be transparent to others. Ideally, anyone who understands the mathematical concept of the sequence at hand and also understands Mathematica should be able to understand how your program computes the sequence. Though one may add another Mathematica program to a sequence entry that already has one if it's less efficient but more clearly shows others that there are other methods to obtain the sequence.

Some things that obscure the transparency of a Mathematica program:

  • Always using the same general method no matter what kind of sequence is being dealt with. For example, recurrence relations can be used to compute lots of sequences. But that's not always the best method for such sequences. Just because the squares can be computed with the recurrence relation , doesn't mean that it wouldn't be better to use something involving "^2" for that purpose.
  • An excessive allegiance to procedural programming. Sometimes it's necessary to inspect numbers one by one and perform a very specific procedure to find the numbers that meet the desired criteria. But some sequences are better computed functionally.
  • An excessive allegiance to functional programming. If your program looks more like a cartoon representation of swear words (e.g., f /@ list # @@@ /. $ -> g &) , clarity may have been compromised.
  • Willfully reinventing the wheel. It's one thing to not know that a particular command that does what you need is a built-in symbol in your current version of Mathematica. It's quite another to reinvent commands that have been around since version 1.0.

About error messages

It is bad manners to turn off error messages on someone else's system. Although no one is forcing Mathematica users to run code from the OEIS, not every Mathematica user knows that error messages can be turned off nor what the commands for doing so are. If you must absolutely turn off error messages for a particular computation, limit the impact to the one computation, and not the rest of the user's session or until they realize error messages have been turned off.

But it is best to rewrite the program so that no error messages are triggered at all. Sometimes it can be a simple matter of skipping over a troublesome argument. Consider:

Table[myFunction[n]/PrimePi[n], {n, 100}]

It should be quite obvious that the above will generate at least one error message, since . But, if myFunction has been properly defined, the following will hopefully cause no errors:

Table[myFunction[n]/PrimePi[n], {n, 2, 100}]

Also keep in mind that there is the General::stop : Further output of [another error message type] will be suppressed during this calculation, which is triggered after three error messages of the same kind. This might not be so bad if the proper results follow immediately after the General::stop message.

Test your programs!

Unless you're copying directly from Mathematica immediately following a successful run, copy and paste from the OEIS to Mathematica and execute. That way you might catch some silly tiny mistake like Fibonaci[n] that causes your program to give nothing besides an error message.

Wolfram Alpha

Programs written specifically in the Wolfram Alpha language are strongly discouraged in the OEIS.

The reason is that Wolfram Alpha also accepts inputs that are not in the formal Mathematica language. One can ask Wolfram Alpha something like: "sum the squares from 1 to n". The problem is that the interpretation of a query expressed in natural language is difficult, sometimes produces unwanted results, and even when it gives the expected result there is no guarantee that next year the same English sentence will be interpreted in the same way.

Since the OEIS is a scientific database, and reproducibility is essential, programs in Wolfram Alpha are discouraged.

Editorial prerogative

You wouldn't be surprised if the Editors corrected some small mistake in your Mathematica program, like a misplaced comma. But the Editors may make more radical changes as they weigh the goals of brevity, speed and transparency.

Nice to have but not essential

Prettyprinting

Just because OEIS sequence entries are limited to monospaced ASCII characters doesn't mean that users have to see that when they copy and paste from the OEIS to Mathematica. Try for example:

\[ExponentialE]^(\[ImaginaryI] \[Pi])

When you hit Ctrl-V in Mathematica, you won't even see the above characters. Instead you will see a blackboard bold lowercase E and likewise a blackboard bold lowercase I and the Greek lowercase letter Pi. Press Enter to confirm these are the numbers you think they are.

But perhaps you're better off just using E, I, Pi, etc.


Flexibility for continued exploration

It's nice when you find a topic that catches other people's interest. If it doesn't bulk up the Mathematica program too much, you can allow others to investigate variants of the topic using your program. Let's say you've considered base 10 "Horace numbers," and others are curious about "Horace numbers" in other bases. It takes just a tiny bit of effort to do something like this:

horaceNumQ[n_Integer, b_:10] := TrueQ[n + Length] etc.

With horaceNumQ[47, 16], someone else can see if 47 is a "Horace number" in hexadecimal, but with just horaceNumQ[47] they ask the question of 47 in base 10 without actually having to type in ", 10".