#include <math.h>
int
Scale (double XMin, double XMax, int N,
double* SMin, double* Step)
// Written by Antonio Gómiz, 1999 based on subroutines
// SCALE (Nelder, 1976) and SCALE (Stirling, 1981)
{
int iNegScl; // Negative scale flag
int iNm1; // Number of scale subintervals
double lfIniStep; // Initial step
double lfSclStep; // Scaled step
double lfTmp; // Temporary value
double lfSclFct; // Scaling back factor
double lfSMax; // Scale maximum value
int it; // Iteration counter
int i; // Neat step counter
// Neat steps
int Steps [] = {10, 12, 15, 16, 20, 25, 30, 40,
50, 60, 75, 80, 100, 120, 150};
int iNS = sizeof (Steps) / sizeof (Steps [0]);
// Some checks
if (XMin > XMax)
{
lfTmp = XMin;
XMin = XMax;
XMax = lfTmp;
}
if (XMin == XMax)
XMax = XMin == 0.0 ? 1.0 : XMin + fabs (XMin) / 10.0;
// Reduce to positive scale case if possible
if (XMax <= 0)
{
iNegScl = 1;
lfTmp = XMin;
XMin = -XMax;
XMax = -lfTmp;
}
else
iNegScl = 0;
if (N < 2) N = 2;
iNm1 = N - 1;
for (it = 0; it < 3; it++)
{
// Compute initial and scaled steps
lfIniStep = (XMax - XMin) / iNm1;
lfSclStep = lfIniStep;
for (; lfSclStep < 10.0; lfSclStep *= 10.0);
for (; lfSclStep > 100.0; lfSclStep /= 10.0);
// Find a suitable neat step
for (i = 0; i < iNS && lfSclStep > Steps [i]; i++);
lfSclFct = lfIniStep / lfSclStep;
// Compute step and scale minimum value
do
{
*Step = lfSclFct * Steps [i];
*SMin = floor (XMin / *Step) * *Step;
lfSMax = *SMin + iNm1 * *Step;
if (XMax <= lfSMax) // Function maximum is in the
// range: the work is done.
{
if (iNegScl) *SMin = -lfSMax;
*Step *= iNm1 / (N - 1);
return 1;
}
i++;
}
while (i < iNS);
// Double number of intervals
iNm1 *= 2;
}
// Could not solve the problem
return 0;
}