MathGroup Archive 2012

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Tips for writing correct, non trivial Mathematica Libraries

  • To: mathgroup at smc.vnet.net
  • Subject: [mg124506] Re: Tips for writing correct, non trivial Mathematica Libraries
  • From: David Bailey <dave at removedbailey.co.uk>
  • Date: Sun, 22 Jan 2012 07:21:11 -0500 (EST)
  • Delivered-to: l-mathgroup@mail-archive0.wolfram.com
  • References: <jf68se$g99$1@smc.vnet.net>

On 18/01/2012 11:02, l.i.b. wrote:

>
> ** Take for example the following: (Taken from the mathematica 8
> virtual book section "Applying Functions to Lists and Other
> Expressions")
>
> geom[list_] := Apply[Times, list]^(1/Length[list])
>
> So, this does a bad thing for geom[ x+ y]  (returns (Sqrt[x y])
>

A lot of Mathematica functions that usually operate on lists, are 
defined more generally so as to apply to any compound object. While this 
can be very useful, it can produce weird results such as this. Simply 
restricting your function to operate only on lists is very easy:

geom[list_List] := Apply[Times, list]^(1/Length[list])

This has the useful feature that geom[Sqrt[x y]] will return without 
change. This is generally valuable, because in general the argument 
might resolve to a list later on, for example

geom[x] /. x->{1,2,3}

Numerical calculations often do weird things is they are applied to 
non-numerical data, so it is often useful to require arguments of a 
function to be numeric:

f[x_?NumericQ]:=Module[{x1=N[x]},
doSomething[x1]
];

The reason for applying N (where appropriate) to the input x, is that a 
numerical algorithm may fail, or operate extremely slowly if forced to 
operate on integer data. To see why that is true, try comparing:

Nest[#^2/(1 + #) &, 22, 4]

with

Nest[#^2/(1 + #) &, 22.0, 4]

Again, the function f will return unchanged if applied to other types of 
arguments, which is exactly what is normally required.

In more complicated cases, it is possible to validate the arguments in 
an arbitrary way using a function definition of the form:

f[args]:=Calculation/;test

Where test can perform any calculation on the arguments, and unless it 
returns True, no evaluation will take place.

Another thing that is almost vital, is to place your library of 
functions in its own package, so that only selected symbols are shared 
with 'the outside world', and to define complicated functions using 
Module or Block, to ensure that they don't use global variables.

You don't want to create a function that works in almost all cases, 
except when someone already has a definition for the variable x! The 
automatic colouring is very useful in this regard.

David Bailey
http://www.dbaileyconsultancy.co.uk



  • Prev by Date: Re: MatrixForm odd behaviour
  • Next by Date: Re: FindRoot and parameters in NIntegrate
  • Previous by thread: Re: Tips for writing correct, non trivial Mathematica Libraries
  • Next by thread: missing Tooltip for ArrayPlot etc. - workaround