mathlib
STATUS: Working. Some terrible code, some good code too. It is slowely being cleaned up and improved.
Aim to build a library of math algorithms. With client control over memory management through templates.
Temporary maths functions are not currently supported in C++. I have addressed this in a C++ way which means that if you do not really get into C++ you might not like the solution.
I have written two macros, one where the functions are constructed and instanciated, the other with macros only. I favor the macros only solution because it has the advantage of directly putting the function within a code body {}.
Here is an example of the template solution.
funcTA1(cubic2,1.0+x*(1.0+x*(1.0+x)),x);
function test()
{
cubic2<double,double> f;
double y = f(1.0);
...
Here is the same cubic with the non-template macro solution.
function test()
{
funcA1(cubic1,1.0+x*(1.0+x*(1.0+x)),x,double,double);
cubic1 f;
double y = f(1.0);
...
In the template version cubic2 class is in the global namespace, in the non-template macro cubic1 is a local class and not in the global namespace, which reduces namespace pollution.
I abstracted the nature of a function in a C++ context. In C++ classes are generally named so the first argument is the class name.
A function has an input and an output or return value, since these can be of different types then the client has to specify what the input and output type is. For the template solution these are the instantiating arguments, for the non-template solution they are the last arguments to the macro.
The number of arguments to a function can vary. The number after A in the macro name refers to the number of arguments the function has. e.g. funcA2 has two arguments.
What we take for granted usually turns out to be more complex that we realize. When I implemented these functions I found that there were common functions which I still could not make.
This lead to functions with local variables. These are initialized in the constructor. The local variables are restricted with a strict naming scheme where the local variables are named v0, v1, .... V in the macro name means variable and the number after it is the number of local variables. Consider the following function with two local variables.
pt2 y; // 2D point pt2 p0(1.0,2.0); pt2 p1(3.5,6.0); funcA1V2(finterp,v0+(v1-v0)*x,x,pt2,double) f(p0,p1); y = f(1.0); ... f(y,2.0);
The other important aspect of a function in C++ is memory - where does it write to. Rather than copying temporary variables around support was added to directly write to the storage location. For example writing a function on an array. We do not want C++ thrashing object construction/desctruction.
To this end two versions of the functional object operator were overloaded. One for the return a value, the other for writing directly.
I am going to have to implement const versions too. This is a must have feature - non negotiable, people who really use const will understand.
So you see that some thought has gone into function generalization and use in C++ here. I am understanding of someone at first hand looking at func.h and getting depressed about it. But I hope that after reading this explanation its better because the goals are clearer.
Generate a continuous random variable from a discrete one using the
standard C rand() function.
The end points are included or excluded by a suffix on random. A 0 indicates exclusion of the point, 1 indicates inclusion. The place indicates whether its the left endpoint or right. For example random01<> indicates that the left interval is open and the right interval is closed, so the sample space may contain 1.
Scaling was not implemented as this was considered the responsibility of the client.
The purpose of including and excluding points is explained through mathematics. Division by zero is an example of a point that causes problems, by excluding the possibility we do not have to consider the consequences. So excluding a point can have real applications for working with functions.
The random number generator and data type were separated through the use of templates. Its quite possible that the client has a much better random number generator, possibly one with another type of distribution. If it has the same interface as randomgenerator it could be slotted in.
rand() has only a limited number of
possibilities and should not be used for large samples.
It really depends if your work is sensitive to the data
which most are
(e.g. iterative converging schemes).