[fpc-pascal] interested in building a library for functions?

Angel Montesinos montesin at uv.es
Thu Feb 24 19:54:48 CET 2011


This is a call for people willing to relieve me in the task of 
maintaining a library for parsing, evaluating and differentiating real 
functions with almost optimal speed and precision without recourse to 
using multiprecision real types. I have it working for years in 
Windows 32 bits, and I think that it could be a nice thing to extend 
it in fpc-Lazarus to other CPU and FPU architectures.

The hardest thing has been already done and tested: to conceive it and 
to build a working model.


    1. SOME HISTORY

For almost thirty years I have been a teacher of differential geometry 
in Valencia, Spain. I retired two years ago. Along these years I have 
written several programs oriented to teaching and research, all for 
Windows 32 bits, and all free. Some of them may be retrieved freely 
and with source code in

    <http://www.uv.es/montesin>

Perhaps the prettiest of them is Superficies_En, wich is an English 
version.  Dont't be afraid by the language barrier for the others: 
almost all sources are written in English.

After studying the code of a library built years ago by Dmitry 
Kaschenko and Vladimir Safin, I wrote first another one with a 
different parsing mechanism and with some safety measures. Then, I 
added the possibility of parsing functions defined with integrals. 
Finally, I added differentiation.

All this done in Delphi with some trials in Kylix and Lazarus.

Now, I feel that I lack the energy and memory to learning the 64 bits 
amd-intel x67 architecture, and the more so for other ones. Thus, I 
may opt by wainting to Delphi 64 bits and then hope for the best, that 
is that by examining the debugging CPU window I become able to 
translate the library to 64 bits. Or else, to provide others with the 
present code (by the way, it has been open in my web page for years) 
and with advice about the underlying theory and tricks. If I find 
interested people, my first task would be to write with more detail my 
notes about the theory and to document better the present code.


    2. OVERVIEW

This is how it works from the viewpoint of the programmer. Integrals
are not included here for brevity:

Supppose the programmer needs, for example, to treat a mathematical 
problem in which some real (that is, with result Double or Extended) 
function in three independent (resp. Double or Extended) variables 
denoted  x, y, z  is to be used. Suppose that the user has input that 
function as the string

    fstr:= 'cos(py + sin(3.22x+ qz^3)) - 1/2',

where  p  and  q  are considered as parameters.

For example, the user wants the program to draw the surface defined 
implicitly by the equation

   cos(py + sin(3.22x+ qz^3)) - 1/2 = 0

The programmer should create an instance of  TOCFunctDDDoubleSafe
by a call as

    theF:= TOCFunctDDDoubleSafe.Create;

Then, the programmer parses  fstr  by a call to

    procedure TOCFunctDDDoubleSafe.ParseNewText(t, vars, pars:
                 AnsiString);

Here,  t  is the string defining the function, vars  is the string 
containing the allowed independent variables, and pars is the string 
containing the allowed parameters. In our case, we could call

    theF.ParseNewText(fstr, 'xyz', 'pq');

If   pars <> '',   the programmer must call at least one time the 
updater of parameter values. That is for instance

    theF.UpdateParameters([3.42, -2.2]);

This means that until another call to UpdateParameters, the parameters 
p and q   will have the values  p = 3.42 and q = -2.2.

Now the programmer may obtain the value of the function by a call as

    a:= theF.F([1.1, 0, sqrt(5)]),

where   a   will be the value of the function when x = 1.1, y = 0 and 
  z = sqrt(5).

For computing the first derivatives of the function, the programmer 
must call

    theF.BuildFirstDerivative;

Then, the following function is available

    TOCFunctDDDoubleSafe.FD(XV: array of Double): Fd;

where

    Fd= record
      f, v: Double;
    end;

And for computing the second derivatives, the programmer must call

    theF.BuildSecondDerivative;

and then the following function is available

    TOCFunctDDDoubleSafe.FDD(XVA: array of Double): Fdd;

where

    Fdd= record
      f, v, a: Double;
    end;

An example: the value of the function and its first partial derivative 
with respect to 'y' at the point (a,b,c) is obtained by calling:

   anFD:= theF.FD([a, b, c, 0, 1, 0]);

So,  anFD.f  shall be the value of the function at (a,b,c), and
anFD.v  shall be the value of that partial derivative at (a,b,c).

In the same manner, the value of the function and its first and second 
partial derivatives with respect to 'y' at the point (a,b,c) are 
obtained by calling:

   anFDD:= theF.FDD([a, b, c, 0, 1, 0, 0, 0, 0]);

So,  anFDD.f  shall be the value of the function at (a,b,c),
anFDD.v  shall be the value of the partial derivative  with respect to 
'y' at (a,b,c), and  anFDD.a  the value of the second partial 
derivative with respect to 'y' at (a,b,c).

The meaning of the three last slots that seem to be useless, and the 
manner for computing crossed partial derivatives requires some 
elaboration that I can provide to the interested persons.

The important thing is that the computation of the function and its 
derivatives is hard-coded in object code without the use of finite 
differences. Thus, one may expect for theF.FD a precision similar to 
that one could obtaine by having precompiled with Delphi (or fpc) the 
function

    function afunction(a, b, c: Double): Fd;
    begin
      fd.x:= cos(p*y + sin(3.22*x+ q*z*sqr(z))) - 1/2
      fd.v:= -p*sin(p*y + sin(3.22*x+ q*z*sqr(z)));
    end;

and the same for theF.DD. In general, my library shall be faster than 
the precompiled function.


   3. MATHEMATICAL BASIS OF DIFFERENTIATION CODE	

Essentially, it is the application of the chain rule to the object 
code. That is, to extend the technique known as "automatic 
differentiation" at the object level of code (instead to the high 
level of code). I do not know whether this is new: I haven't found it 
the computing literature: at least when I began to write it. After I 
wrote it, I haven't had the need to search for it. If you know of 
something similar, tell me please.

Googling for "automatic differentiation" could give an initial idea of 
the underlying mechanism.

If you download the full distro of Superficies_En, you will see in the 
source folder a file with title:

"Object code for the first and second differential of a function 
with the instruction set x86.rtf"

It is a roughly written report about the thing, excluding integration.
About integration, I use splines for interpolation: see in that folder 
the file  "AproxFuncBSplinesEnglish.pdf". I think that my technique 
for B-spline interpolation is also new, but I am not sure of it.

The relevant pascal unit in the source folder is

    OCFunctDDDoubleSafeIntegrals.pas


Best regards


-- 
montesin at uv dot es




More information about the fpc-pascal mailing list