Subject: interface for numerical integration, roots etc
From: John Lapeyre
Date: Tue, 25 May 2010 22:51:43 +0200
Hi,
I made a start on writing emulators for Mma NIntegrate
and FindRoot.
The code is at:
https://sourceforge.net/projects/ribot/files/
Since there has been interest in developing the interface in
maxima proper, I thought it might be better to write a
maxima interface and write an Mma-like wrapper, rather than
the other way around.
One of the main issues is how to pass options (these functions
take many options). It would be nice to have a uniform, flexible
system. For instance in perl, {} constructs an anonymous hash,
which can be used to pass options
foo( x,y,x, { OPT1 => 1, OPT2 => "cat" })
Mma uses OptionA -> 1, which is a special syntax for
Rule(OptionA,1). So I use a routine that filters these
rules from an argument list and stores them in a hash.
But, it's not clear that this is the best way to implement
something like this for maxima (assuming people want to get
away from a big pile of randomly named global variables and
a flat list of FORTRAN inspired arguments). I do like groupimg
iterator-like things as lists-- [x,a,b]. They are easier to read,
offer a more flexible interface, and are easy to process.
As said, I'd rather find something for maxima and then put an Mma layer
on it-- something that is not so much of an issue with
Array,Table,Tuples, etc. Maybe its enough to only change Rule to rule
and FunctionName to function_name... Or maybe
options(op1,val1,opt2,val2,...)
Using 'esprel=10-3 as in the maxima quadpack interface is tempting,
but not as a general soution because they look like equations.
Maybe options( 'opt1=val1, ...) (and I think there may be
a way to automatically quote all the LHS's ?)
Following are notes on the current NIntegrate and FindRoot, which is
working fairly well. There is a large amount of documentation on
the Mma functions online. Notice that find_root , newton, romberg,
and quadpack are somewhat unified by this interface. There are
many more examples in tests/rtest_mixima.mac and
tests/rtest_nintegrate.mac.
* NIntegrate
This makes calls to the maxima quadpack and romberg routines.
Multiple integrals are implemented automatically as in Mma, but via nesting, which is slow.
Details of the call are different from Mma. Here is an example call
NIntegrate(sin(sin(x)),[x,0,2], Rule(Method,NewtonCotesRule),
Rule(MinRecursion,2),Rule(MaxRecursion,12),Rule(PrecisionGoal,10),Rule(AccuracyGoal,Infinity);
Specifiying the Rules is optional.
Method can be one of Automatic NewtonCotesRule=RombergRule QagsRule Oscillatory=GaussKronrodRule6
GaussKronrod=GaussKronrodRule=GaussKronrodRule1
GaussKronrodRule2 GaussKronrodRule3 GaussKronrodRule4 GaussKronrodRule5
Some rules are duplicated for deprecated Mma
options. Here, the Rule Oscillatory does not work with
infinite intervals, whereas in Mma 3.0 it *only* works
with infinite intervals
The default Method is Automatic which makes a few tests to
choose a method: Eg, Infinite interval, singularity at endpoints.
It is a good start, but needs improvment.
Other options are PrecisionGoal and AccuracyGoal. Options
MinRecursion and MaxRecursion are only used with
RombergRule method. See examples in
tests/rtest_mixima_nintegrate.mac
* FindRoot
With two boundary points, the secant method in maxima find_root is used.
Examples:
FindRoot(sin(x) = x/2,[ x, 0.1, %pi]);
FindRoot(sin(x) - x/2,[ x, 0.1, %pi], Rule(PrecisionGoal,3), Rule(AccuracyGoal,10));
FindRoot(sin(x) - x/2,[ x, 0.1, %pi]);
With one starting point, Newton's method is used (using a modified version of the
maxima function to include, for instance, a limit on the number of iterations).
Examples:
FindRoot(sin(x) = x/2,[ x, 1.0]);
FindRoot(sin(x) = x/2,[ x, 1.0],Rule(MaxIterations,10));
FindRoot(sin(x) - x/2,[ x, 1.0]);
The options PrecisionGoal and AccuracyGoal are supported by the secant method.
The options AccuracyGoal and MaxIterations are supported by Newton's method.
Note that in Newton's method AccuracyGoal determines how close the function evaluation
must be to zero, not how close the variable will be to it's true value.
Eg, the default AccuracyGoal is 6, but
FindRoot(((Sin((x-10))-x)+10),[x,0]); gives 9.98318 .
I more sophisticated stopping criterion ought to be used.
John