| sampled_gaussian.cpp.html | mathcode2html |
| Source file: sampled_gaussian.cpp | |
| Converted: Tue Apr 17 2012 at 11:03:44 | |
| This documentation file will not reflect any later changes in the source file. |
$$\phantom{******** If you see this on the webpage then the
browser could not locate *********}$$
$$\phantom{******** jsMath/easy/load.js or the variable root
is set wrong in this file *********}$$
$$\newcommand{\vector}[1]{\left[\begin{array}{c} #1 \end{array}\right]}$$
$$\newenvironment{matrix}{\left[\begin{array}{cccccccccc}} {\end{array}\right]}$$
$$\newcommand{\A}{{\cal A}}$$
$$\newcommand{\W}{{\cal W}}$$
/* Copyright 2008-2011 Research Foundation State University of New York */
/* This file is part of QUB Express. */
/* QUB Express is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation, either version 3 of the License, or */
/* (at your option) any later version. */
/* QUB Express is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* You should have received a copy of the GNU General Public License, */
/* named LICENSE.txt, in the QUB Express program directory. If not, see */
/* <http://www.gnu.org/licenses/>. */
#include <math.h>
#include <string.h>
#include <iostream>
#include "sampled_gaussian.h"
using namespace std;
#ifndef NULL
#define NULL 0
#endif
#ifdef _WIN32
#include <boost/math/special_functions/erf.hpp>
using boost::math::erf;
#endif
SampledGaussian::SampledGaussian()
: A(NULL)
{
setup(0.0, 1.0, 1e-3, 6.0, 256, false);
}
SampledGaussian::SampledGaussian(const SampledGaussian& other)
: mean(other.mean), std(other.std), resolution(other.resolution), cutoff_std(other.cutoff_std),
s2s2i(other.s2s2i), r2(other.r2), max_for_complete(other.max_for_complete), N(other.N),
A(other.A ? new double[other.N] : NULL), A_out(other.A_out), y2i_m(other.y2i_m), y2i_b(other.y2i_b),
use_log(other.use_log)
{
if ( A )
memcpy(A, other.A, N*sizeof(double));
}
SampledGaussian& SampledGaussian::operator=(const SampledGaussian& other)
{
delete [] A;
mean = other.mean;
std = other.std;
resolution = other.resolution;
cutoff_std = other.cutoff_std;
s2s2i = other.s2s2i;
r2 = other.r2;
max_for_complete = other.max_for_complete;
N = other.N;
A = other.A ? new double[other.N] : NULL;
A_out = other.A_out;
y2i_m = other.y2i_m;
y2i_b = other.y2i_b;
use_log = other.use_log;
return *this;
}
void SampledGaussian::setup(double mean_, double std_, double resolution_,
double cutoff_std_, int max_for_complete_, bool sample, bool use_log_)
{
delete [] A;
A = NULL;
mean = mean_;
std = std_;
resolution = resolution_;
cutoff_std = cutoff_std_;
max_for_complete = max_for_complete_;
use_log = use_log_;
s2s2i = 1.0 / (std * sqrt(2.0));
r2 = resolution / 2.0;
N = (int) (2 * std * cutoff_std / resolution + 0.5);
if ( (! sample) || (N > max_for_complete) ) {
//cerr << "non-sampled " << mean << " +/- " << std << " -> " << N << " at " << resolution << endl;
N = 0;
} else {
make_A();
}
}
void SampledGaussian::make_A()
{
A = new double[N];
double cdf_b = 0.0;
double b = mean - std * cutoff_std;
for (int i=0; i<N; ++i) {
double a = b;
double cdf_a = cdf_b ? cdf_b : erf((a - mean) * s2s2i);
b += resolution;
cdf_b = erf((b - mean) * s2s2i);
A[i] = 0.5 * (cdf_b - cdf_a);
if ( use_log )
A[i] = log(A[i]);
}
A_out = G_area(mean+(cutoff_std+1)*std, mean+(cutoff_std+1)*std + resolution);
y2i_m = N / (2 * std * cutoff_std);
y2i_b = N/2.0 - mean * y2i_m;
}
SampledGaussian::~SampledGaussian()
{
delete [] A;
}
double SampledGaussian::operator()(double x)
{
return N ? G_sampled(x) : G_centered(x);
}
double SampledGaussian::G_area(double a, double b)
{
if ( use_log )
return log(0.5 * (erf((b - mean) * s2s2i) - erf((a - mean) * s2s2i)));
else
return 0.5 * (erf((b - mean) * s2s2i) - erf((a - mean) * s2s2i));
}
double SampledGaussian::G_centered(double x)
{
return G_area(x - r2, x + r2);
}
double SampledGaussian::G_sampled(double x)
{
int i = (int) (y2i_m * x + y2i_b);
if ( (0 <= i) && (i < N) )
return A[i];
return A_out;
}