Question:
I have a certain number of float random variables in the range [0; 1] and these values have a uniform distribution.
If such a quantity X has a normal distribution, then the quantity
K = m + a * tan (PI * (X-0.5)) has a Cauchy distribution.
Is it possible, by analogy, to transform such a quantity X into a quantity with a normal distribution?
Answer:
I wrote roughly and accurately (2.5%) the InverseErf function. It is very difficult to compute.
// g++ inverf.cpp -o inverf
# include <math.h>
# include <iostream>
// -1 => -Inf ; 0 => 0 ; +1 => Inf
// -0.82 .. +0.82 => третья степень
// 0.82 .. 1.0 => сложно
double InverseErf(double x){
bool flagneg = (x < 0.0);
x=fabs(x);
double result;
if(x<0.82) result = (x*x*0.37+0.88)*x;
else {
x=log(1.0-x);
double const HalfPi = 1.57 ;
result = sqrt(-x-log(-HalfPi*(log(HalfPi)+2.0*x))/2.0);}
return flagneg ? -result : result ; }
double SimpleToNormal(double x , double med , double sigma){
return med + sqrt(2.0)*sigma*InverseErf(2.0*x-1.0);}
int main() {
std::cout<<"inverf(0.999)="<<InverseErf(0.999)<<std::endl;
std::cout<<"inverf(0.99)="<<InverseErf(0.99)<<std::endl;
std::cout<<"inverf(0.9)="<<InverseErf(0.9)<<std::endl;
std::cout<<"inverf(0.75)="<<InverseErf(0.75)<<std::endl;
double med = 0.0;
double sig = 1.0;
std::cout<<"0.999: "<<SimpleToNormal(0.999,med,sig)<<std::endl;
std::cout<<"0.99: "<<SimpleToNormal(0.99,med,sig)<<std::endl;
std::cout<<"0.9: "<<SimpleToNormal(0.9,med,sig)<<std::endl;
std::cout<<"0.75: "<<SimpleToNormal(0.75,med,sig)<<std::endl; }
Muller's method provoked another beautiful (not accurate) version of the InverseErf formula:
double InverseErf(double x){
double result = sqrt(-log(1.0-x*x))*0.9;
return (x < 0.0) ? -result : result ; }