using System;
namespace Legalsoft.Truffer
{
public class Miser
{
const int RANSEED = 5331;
static Ran ran = new Ran(RANSEED);
public Miser()
{
}
public static void ranpt(double[] pt, double[] regn)
{
int n = pt.Length;
for (int j = 0; j < n; j++)
{
pt[j] = regn[j] + (regn[n + j] - regn[j]) * ran.doub();
}
}
///
/// Monte Carlo samples a user-supplied ndim-dimensional function func in a
/// rectangular volume specified by regn[0..2 * ndim - 1], a vector consisting of
/// ndim "lower-left" coordinates of the region followed by ndim "upper-right"
/// coordinates.The function is sampled a total of npts times, at locations
/// determined by the method of recursive stratified sampling.The mean value
/// of the function in the region is returned as ave; an estimate of the
/// statistical uncertainty of ave(square of standard deviation) is returned
/// as var.The input parameter dith should normally be set to zero, but can be
/// set to(e.g.) 0.1 if func's active region falls on the boundary of a
/// power-of-two subdivision of region.
///
///
///
///
///
///
public static void miser(RealValueFun func, double[] regn, int npts, double dith, ref double ave, ref double xvar)
{
const int MNPT = 15;
const int MNBS = 60;
const double PFAC = 0.1;
const double TINY = 1.0e-30;
const double BIG = 1.0e30;
int iran = 0;
int ndim = regn.Length / 2;
double[] pt = new double[ndim];
if (npts < MNBS)
{
double summ = 0.0;
double summ2 = 0.0;
for (int n = 0; n < npts; n++)
{
ranpt(pt, regn);
double fval = func.funk(pt);
summ += fval;
summ2 += fval * fval;
}
ave = summ / npts;
xvar = Math.Max(TINY, (summ2 - summ * summ / npts) / (npts * npts));
}
else
{
double[] rmid = new double[ndim];
int npre = Math.Max((int)(npts * PFAC), (int)MNPT);
double[] fmaxl = new double[ndim];
double[] fmaxr = new double[ndim];
double[] fminl = new double[ndim];
double[] fminr = new double[ndim];
for (int j = 0; j < ndim; j++)
{
iran = (iran * 2661 + 36979) % 175000;
double s = Globals.SIGN(dith, (double)(iran - 87500));
rmid[j] = (0.5 + s) * regn[j] + (0.5 - s) * regn[ndim + j];
fminl[j] = fminr[j] = BIG;
fmaxl[j] = fmaxr[j] = (-BIG);
}
for (int n = 0; n < npre; n++)
{
ranpt(pt, regn);
double fval = func.funk(pt);
for (int j = 0; j < ndim; j++)
{
if (pt[j] <= rmid[j])
{
fminl[j] = Math.Min(fminl[j], fval);
fmaxl[j] = Math.Max(fmaxl[j], fval);
}
else
{
fminr[j] = Math.Min(fminr[j], fval);
fmaxr[j] = Math.Max(fmaxr[j], fval);
}
}
}
double sumb = BIG;
int jb = -1;
double siglb = 1.0;
double sigrb = 1.0;
for (int j = 0; j < ndim; j++)
{
if (fmaxl[j] > fminl[j] && fmaxr[j] > fminr[j])
{
double sigl = Math.Max(TINY, Math.Pow(fmaxl[j] - fminl[j], 2.0 / 3.0));
double sigr = Math.Max(TINY, Math.Pow(fmaxr[j] - fminr[j], 2.0 / 3.0));
double sum = sigl + sigr;
if (sum <= sumb)
{
sumb = sum;
jb = j;
siglb = sigl;
sigrb = sigr;
}
}
}
if (jb == -1)
{
jb = (ndim * iran) / 175000;
}
double rgl = regn[jb];
double rgm = rmid[jb];
double rgr = regn[ndim + jb];
double fracl = Math.Abs((rgm - rgl) / (rgr - rgl));
int nptl = (int)(MNPT + (npts - npre - 2 * MNPT) * fracl * siglb / (fracl * siglb + (1.0 - fracl) * sigrb));
int nptr = npts - npre - nptl;
double[] regn_temp = new double[2 * ndim];
for (int j = 0; j < ndim; j++)
{
regn_temp[j] = regn[j];
regn_temp[ndim + j] = regn[ndim + j];
}
regn_temp[ndim + jb] = rmid[jb];
double avel = 0.0;
double varl = 0.0;
miser(func, regn_temp, nptl, dith, ref avel, ref varl);
regn_temp[jb] = rmid[jb];
regn_temp[ndim + jb] = regn[ndim + jb];
miser(func, regn_temp, nptr, dith, ref ave, ref xvar);
ave = fracl * avel + (1 - fracl) * ave;
xvar = fracl * fracl * varl + (1 - fracl) * (1 - fracl) * xvar;
}
}
}
}
using System;
namespace Legalsoft.Truffer
{
public class Miser
{
const int RANSEED = 5331;
static Ran ran = new Ran(RANSEED);
public Miser()
{
}
public static void ranpt(double[] pt, double[] regn)
{
int n = pt.Length;
for (int j = 0; j < n; j++)
{
pt[j] = regn[j] + (regn[n + j] - regn[j]) * ran.doub();
}
}
///
/// Monte Carlo samples a user-supplied ndim-dimensional function func in a
/// rectangular volume specified by regn[0..2 * ndim - 1], a vector consisting of
/// ndim "lower-left" coordinates of the region followed by ndim "upper-right"
/// coordinates.The function is sampled a total of npts times, at locations
/// determined by the method of recursive stratified sampling.The mean value
/// of the function in the region is returned as ave; an estimate of the
/// statistical uncertainty of ave(square of standard deviation) is returned
/// as var.The input parameter dith should normally be set to zero, but can be
/// set to(e.g.) 0.1 if func's active region falls on the boundary of a
/// power-of-two subdivision of region.
///
///
///
///
///
///
public static void miser(RealValueFun func, double[] regn, int npts, double dith, ref double ave, ref double xvar)
{
const int MNPT = 15;
const int MNBS = 60;
const double PFAC = 0.1;
const double TINY = 1.0e-30;
const double BIG = 1.0e30;
int iran = 0;
int ndim = regn.Length / 2;
double[] pt = new double[ndim];
if (npts < MNBS)
{
double summ = 0.0;
double summ2 = 0.0;
for (int n = 0; n < npts; n++)
{
ranpt(pt, regn);
double fval = func.funk(pt);
summ += fval;
summ2 += fval * fval;
}
ave = summ / npts;
xvar = Math.Max(TINY, (summ2 - summ * summ / npts) / (npts * npts));
}
else
{
double[] rmid = new double[ndim];
int npre = Math.Max((int)(npts * PFAC), (int)MNPT);
double[] fmaxl = new double[ndim];
double[] fmaxr = new double[ndim];
double[] fminl = new double[ndim];
double[] fminr = new double[ndim];
for (int j = 0; j < ndim; j++)
{
iran = (iran * 2661 + 36979) % 175000;
double s = Globals.SIGN(dith, (double)(iran - 87500));
rmid[j] = (0.5 + s) * regn[j] + (0.5 - s) * regn[ndim + j];
fminl[j] = fminr[j] = BIG;
fmaxl[j] = fmaxr[j] = (-BIG);
}
for (int n = 0; n < npre; n++)
{
ranpt(pt, regn);
double fval = func.funk(pt);
for (int j = 0; j < ndim; j++)
{
if (pt[j] <= rmid[j])
{
fminl[j] = Math.Min(fminl[j], fval);
fmaxl[j] = Math.Max(fmaxl[j], fval);
}
else
{
fminr[j] = Math.Min(fminr[j], fval);
fmaxr[j] = Math.Max(fmaxr[j], fval);
}
}
}
double sumb = BIG;
int jb = -1;
double siglb = 1.0;
double sigrb = 1.0;
for (int j = 0; j < ndim; j++)
{
if (fmaxl[j] > fminl[j] && fmaxr[j] > fminr[j])
{
double sigl = Math.Max(TINY, Math.Pow(fmaxl[j] - fminl[j], 2.0 / 3.0));
double sigr = Math.Max(TINY, Math.Pow(fmaxr[j] - fminr[j], 2.0 / 3.0));
double sum = sigl + sigr;
if (sum <= sumb)
{
sumb = sum;
jb = j;
siglb = sigl;
sigrb = sigr;
}
}
}
if (jb == -1)
{
jb = (ndim * iran) / 175000;
}
double rgl = regn[jb];
double rgm = rmid[jb];
double rgr = regn[ndim + jb];
double fracl = Math.Abs((rgm - rgl) / (rgr - rgl));
int nptl = (int)(MNPT + (npts - npre - 2 * MNPT) * fracl * siglb / (fracl * siglb + (1.0 - fracl) * sigrb));
int nptr = npts - npre - nptl;
double[] regn_temp = new double[2 * ndim];
for (int j = 0; j < ndim; j++)
{
regn_temp[j] = regn[j];
regn_temp[ndim + j] = regn[ndim + j];
}
regn_temp[ndim + jb] = rmid[jb];
double avel = 0.0;
double varl = 0.0;
miser(func, regn_temp, nptl, dith, ref avel, ref varl);
regn_temp[jb] = rmid[jb];
regn_temp[ndim + jb] = regn[ndim + jb];
miser(func, regn_temp, nptr, dith, ref ave, ref xvar);
ave = fracl * avel + (1 - fracl) * ave;
xvar = fracl * fracl * varl + (1 - fracl) * (1 - fracl) * xvar;
}
}
}
}