⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 random.c

📁 贝叶斯算法:盲分离技术
💻 C
📖 第 1 页 / 共 5 页
字号:
        }
        else if( g + v + a * x < 0.0 )
        {
            y = g + v + a * x + Rangauss(Rand);
            accept = (y > 0.0) ? -2.0 * v * y : 0.0;
        }
        else
        {
            y = Rangauss(Rand);
            accept = (g + a * x) * y - v * fabs(y);
        }
    } while( accept < 0.0 && accept < log(Randouble(Rand)) );
// Exit
    *x0 = x;
    *y0 = y;
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Function:  Posneg2A
// 
// Purpose:   Set bi-exponential sampler for Posneg2 in case a > 0, g >= v
//                 
//                    | exp  - x^2 / 2 + f x - u x + (g - v + a x)^2 / 2
//      x = 0         |
//                    | exp  - x^2 / 2 + f x + u x + (g - v + a x)^2 / 2
//     x2 = -(g-v)/a  |
//                    | exp  - x^2 / 2 + f x + u x
//     x1 = -(g+v)/a  |
//                    | exp  - x^2 / 2 + f x + u x + (g + v + a x)^2 / 2
//         
// History:   JS         31 Dec 2001, 3 Oct 2002
//-----------------------------------------------------------------------------
// 
static void Posneg2A(
double  fpu,      // I    f + u  > 0
double  fmu,      // I    f - u  <= gmv
double  gpv,      // I    g + v  > 0
double  gmv,      // I    g - v  >= 0
double  a,        // I    > 0
double  height,   // I    height of sampler cusp above target maximum
double* xc,       //   O  target maximum
double* p0,       //   O  sampler  exp( yc + p0 * (x-xc) ),  x < xc  (p0 > 0)
double* q0)       //   O  sampler  exp( yc + q0 * (x-xc) ),  x > xc  (q0 < 0)
{
    double  x1, x2, y0, y1, y2, m0, m1, m2, m9, xcap, ycap;
    double  d, p, q, r, s, t, u;
    d = 1.0 - a * a;
    if( d < DBL_EPSILON )
        d = DBL_EPSILON;

// Set boundaries  ...(x1,y1)...(x2,y2)...(0,y0)...
// and slopes            m1        m2     m9,m0
    x1 = -gpv / a;
    y1 = x1 * (fpu - 0.5 * x1);
    m1 = fpu - x1;

    x2 = -gmv / a;
    y2 = x2 * (fpu - 0.5 * x2);
    m2 = fpu - x2;

    y0 = 0.5 * gmv * gmv;
    m9 = fpu + a * gmv;                 // +ve
    m0 = fmu + a * gmv;

// Find apex from slope=0 
    if( m0 <= 0.0 )                     // apex at 0
    {
        xcap = 0.0;
        ycap = height + y0;

        if(ycap <= y2 - m2*x2)    // Lslope(xcap,ycap,-d/2,fpu+a*gmv,gmv*gmv/2)
            p = m9 + sqrt(2.0 * d * height);
        else
        {
            r = (ycap - y1) + m1 * x1;
            if( r <= 0.0 )        // Lslope(xcap, ycap, -1/2., fpu, 0)
                p = fpu + sqrt(2.0 * ycap);
            else                  // Lslope(xcap,ycap,-d/2,fpu+a*gpv,gpv*gpv/2)
                p = (fpu + a * gpv) + sqrt(2.0 * d * (d * ycap + a * a * r));
        }                         // Rslope(xcap,ycap,-d/2,fmu+a*gmv,gmv*gmv/2)
        q = m0 - sqrt(2.0 * d * height);
    }
    else                                // apex in (0,inf)
    {
        xcap = m0 / d;
        ycap = height + 0.5 * (d * xcap * xcap + gmv * gmv);

        if(ycap - y0 <= m0*xcap)  // Lslope(xcap,ycap,-d/2,fmu+a*gmv,gmv*gmv/2)
            p = sqrt(2.0 * d * height);
        else
        {
            r = (ycap - y0) - m9 * xcap;
            if( r <= 0.0 )
                p = (ycap - y0) / xcap;
            else
            {
                s = (ycap - y2) - m2 * (xcap - x2);
                if( s <= 0.0 )    // Lslope(xcap,ycap,-d/2,fpu+a*gmv,gmv*gmv/2)
                    p = (fpu - fmu) + sqrt(d * (2.0 * r + d * xcap * xcap));
                else
                {
                    t = (ycap - y1) - m1 * (xcap - x1);
                    if( t <= 0.0 )
                    {             // Lslope(xcap,ycap,-1/2.,fpu,0)
                        u = 2.0 * s - 2.0 * xcap * x2 + x2 * x2;
                        p = fpu + u / (xcap + sqrt(u + xcap * xcap));
                    }
                    else
                    {             // Lslope(xcap,ycap,-d/2,fpu+a*gpv,gpv*gpv/2)
                        u = fmu + a * gmv + d * gpv / a;
                        p = ((fpu - fmu) + a * (gpv - gmv))
                                            + sqrt(2.0 * d * t + u * u);
                    }
                }
            }
        }                         // Rslope(xcap,ycap,-d/2,fmu+a*gmv,gmv*gmv/2)
        q = -sqrt(2.0 * d * height);
    }

    *xc = xcap;
    *p0 = p;
    *q0 = q;
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Function:  Posneg2B
// 
// Purpose:   Set bi-exponential sampler for Posneg2 in case a > 0, g <= v
//                 
//                    | exp  - x^2 / 2 + f x - u x + (g - v + a x)^2 / 2
//     x2 = (v-g)/a   |
//                    | exp  - x^2 / 2 + f x - u x
//      x = 0         |
//                    | exp  - x^2 / 2 + f x + u x
//     x1 = -(v+g)/a  |
//                    | exp  - x^2 / 2 + f x + u x + (g + v + a x)^2 / 2
//                 
// History:   JS         31 Dec 2001, 3 Oct 2002
//-----------------------------------------------------------------------------
// 
static void Posneg2B(
double  fpu,      // I    f + u  > 0
double  fmu,      // I    f - u  <= gmv
double  gpv,      // I    g + v  > 0
double  gmv,      // I    g - v  <= 0
double  a,        // I    > 0
double  height,   // I    height of sampler cusp above target maximum
double* xc,       //   O  target maximum
double* p0,       //   O  sampler  exp( yc + p0 * (x-xc) ),  x < xc  (p0 > 0)
double* q0)       //   O  sampler  exp( yc + q0 * (x-xc) ),  x > xc  (q0 < 0)
{
    double  x1, x2, y1, y2, m1, m2;
    double  d, p, q, t;
    d = 1.0 - a * a;
    if( d < DBL_EPSILON )
        d = DBL_EPSILON;

// Set boundaries  ...(x1,y1)...(0,y0)...(x2,y2)...
// and slopes            m1    +ve,-ve      m2
    x1 = -gpv / a;
    y1 = x1 * (fpu - 0.5 * x1);
    m1 = fpu - x1;

    x2 = -gmv / a;
    y2 = x2 * (fmu - 0.5 * x2);
    m2 = fmu - x2;

// Apex necessarily at 0 
    t = m1 * x1 - (y1 - height);
    if( t <= 0.0 )                 // Lslope(0,height,-1/2.,fpu,0)
        p = fpu + sqrt(2.0 * height);
    else                           // Lslope(0,height,-d/2,fpu+a*gpv,gpv*gpv/2)
        p = (fpu + a * gpv) + sqrt(d * (2.0 * t + d * x1 * x1));

    t = m2 * x2 - (y2 - height);
    if( t <= 0.0 )                 // Rslope(0,height,-1/2.,fmu,0)
        q = fmu - sqrt(2.0 * height);
    else                           // Rslope(0,height,-d/2,fmu+a*gmv,gmv*gmv/2)
        q = (fmu + a * gmv) - sqrt(d * (2.0 * t + d * x2 * x2));

    *xc = 0.0;
    *p0 = p;
    *q0 = q;
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Function:  Posneg2C
// 
// Purpose:   Set bi-exponential sampler for Posneg2 in case a < 0, g >= v
//                 
//                    | exp  - x^2 / 2 + f x - u x + (g + v + a x)^2 / 2
//     x2 = (g+v)/-a  |
//                    | exp  - x^2 / 2 + f x - u x
//     x1 = (g-v)/-a  |
//                    | exp  - x^2 / 2 + f x - u x + (g - v + a x)^2 / 2
//      x = 0         |
//                    | exp  - x^2 / 2 + f x + u x + (g - v + a x)^2 / 2
//                 
// History:   JS         31 Dec 2001, 3 Oct 2002
//-----------------------------------------------------------------------------
// 
static void Posneg2C(
double  fpu,      // I    f + u  > 0
double  fmu,      // I    f - u  <= gmv
double  gpv,      // I    g + v  > 0
double  gmv,      // I    g - v  >= 0
double  a,        // I    < 0
double  height,   // I    height of sampler cusp above target maximum
double* xc,       //   O  target maximum
double* p0,       //   O  sampler  exp( yc + p0 * (x-xc) ),  x < xc  (p0 > 0)
double* q0)       //   O  sampler  exp( yc + q0 * (x-xc) ),  x > xc  (q0 < 0)
{
    double  x1, x2, y0, y1, y2, m0, m1, m2, m9, xcap, ycap;
    double  d, p, q, r, s, t, u, v, w;
    d = 1.0 - a * a;
    if( d < DBL_EPSILON )
        d = DBL_EPSILON;

// Set boundaries  ...(0,y0)...(x1,y1)...(x2,y2)...
// and slopes         m9,m0      m1        m2
    x1 = -gmv / a;
    y1 = x1 * (fmu - 0.5 * x1);
    m1 = fmu - x1;                      // -ve

    x2 = -gpv / a;
    y2 = x2 * (fmu - 0.5 * x2);
    m2 = fmu - x2;

    y0 = 0.5 * gmv * gmv;
    m9 = fpu + a * gmv;
    m0 = fmu + a * gmv;

// Find apex from slope=0 
    if( m9 < 0.0 )                      // apex in (-inf,0)
    {
        xcap = m9 / d;
        ycap = height + 0.5 * (d * xcap * xcap + gmv * gmv);

        p = sqrt(2. * d * height);// Lslope(xcap,ycap,-d/2,fpu+a*gmv,gmv*gmv/2)
        r = (ycap - y0) - m9 * xcap;
        if( r <= 0.0 )            // Rslope(xcap,ycap,-d/2,fpu+a*gmv,gmv*gmv/2)
            q = -sqrt(2.0 * d * height);
        else
        {
            s = ycap - y0 - m0 * xcap;
            if( s <= 0.0 )
                q = (ycap - y0) / xcap;
            else
            {
                t = (ycap - y1) - m1 * (xcap - x1);
                if( t <= 0.0 )    // Rslope(xcap,ycap,-d/2,fmu+a*gmv,gmv*gmv/2)
                    q = (fmu - fpu) - sqrt(2.0 * d * s + m9 * m9);
                else
                {
                    u = (ycap - y2) - m2 * (xcap - x2);
                    if( u <= 0.0 )
                    {             // Rslope(xcap,ycap,-1/2.,fmu,0)
                        v = 2.0 * t + (x1 - xcap) * (x1 - xcap);
                        w = (x1 * (1.0 - a) - 2.0 * xcap) * x1 * (1.0 + a);
                        q = (fmu - gmv)
                           - (2.0 * t + w) / (gmv - xcap + sqrt(v));
                    }
                    else
                    {             // Rslope(xcap,ycap,-d/2,fmu+a*gpv,gpv*gpv/2)
                        v = d * (2.0 * u + d * (x2 - xcap) * (x2 - xcap));
                        w = (fmu - fpu) - a * (gmv - gpv);
                        q = w - sqrt(v);
                    }
                }
            }
        }
    }
    else if( m0 <= 0.0 )                 // apex at 0
    {
        xcap = 0.0;
        ycap = height + 0.5 * gmv * gmv;
                                  // Lslope(xcap,ycap,-d/2,fpu+a*gmv,gmv*gmv/2)
        p = m9 + sqrt(2.0 * d * height);

        r = ycap - y1 + m1 * x1;
        if( r <= 0.0 )            // Rslope(xcap,ycap,-d/2,fmu+a*gmv,gmv*gmv/2)
            q = m0 - sqrt(2.0 * d * height);
        else
        {
            s = ycap - y2 + m2 * x2;
            if( s <= 0.0 )        // Rslope(xcap,ycap,-1/2.,fmu,0)
                q = (fmu - gmv) - 2.0 * height / (gmv + sqrt(2.0 * ycap));
            else                  // Rslope(xcap,ycap,-d/2,fmu+a*gpv,gpv*gpv/2)
                q = (a * (gpv - gmv) + m0) - sqrt(d * (2.0 * s + d * x2 * x2));
        }
    }
    else                                // apex in (0,x1)
    {
        xcap = m0 / d;
        ycap = height + 0.5 * (d * xcap * xcap + gmv * gmv);

        r = ycap - y0 - m0 * xcap;
        if( r <= 0.0 )            // Lslope(xcap,ycap,-d/2,fmu+a*gmv,gmv*gmv/2)
            p = sqrt(2.0 * d * height);
        else
        {
            s = ycap - y0 - m9 * xcap;
            if( s <= 0.0 )
                p = (ycap - y0) / xcap;
            else                  // Lslope(xcap,ycap,-d/2,fpu+a*gmv,gmv*gmv/2)
                p = (fpu - fmu) + sqrt(d * (2.0 * s + d * xcap * xcap));
        }

        r = ycap - y1 - m1 * (xcap - x1);
        if( r <= 0.0 )            // Rslope(xcap,ycap,-d/2,fmu+a*gmv,gmv*gmv/2)
            q = -sqrt(2.0 * d * height);
        else
        {
            s = ycap - y2 - m2 * (xcap - x2);
            if( s <= 0.0 )
            {                     // Rslope(xcap,ycap,-1/2.,fmu,0)
                v = 2.0 * r + (fmu - x1) * (fmu - x1) * (1.0 + a * a) / d;
                w = (a * (gmv - fmu) - (1.0 + a) * gmv) * a / d;
                q = -v / (w + sqrt(2.0 * r + (xcap - x1) * (xcap - x1)));
            }
            else                  // Rslope(xcap,ycap,-d/2,fmu+a*gpv,gpv*gpv/2)
                q = a * (gpv - gmv)
                   - sqrt(d * (2.0 * s + d * (xcap - x2) * (xcap - x2)));
        }
    }

    *xc = xcap;
    *p0 = p;
    *q0 = q;
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Function:  Posneg2D
// 
// Purpose:   Set bi-exponential sampler for Posneg2 in case a < 0, g <= v
//                 
//                    | exp  - x^2 / 2 + f x - u x + (g + v + a x)^2 / 2
//     x2 = (v+g)/-a  |
//                    | exp  - x^2 / 2 + f x - u x
//      x = 0         |
//                    | exp  - x^2 / 2 + f x + u x
//     x1 = -(v-g)/-a |
//                    | exp  - x^2 / 2 + f x + u x + (g - v + a x)^2 / 2
//                 
// History:   JS         31 Dec 2001, 3 Oct 2002
//-----------------------------------------------------------------------------
// 
static void Posneg2D(
double  fpu,      // I    f + u  > 0
double  fmu,      // I    f - u  <= gmv
double  gpv,      // I    g + v  > 0
double  gmv,      // I    g - v  <= 0
double  a,        // I    < 0
double  height,   // I    height of sampler cusp above target maximum
double* xc,       //   O  target maximum
double* p0,       //   O  sampler  exp( yc + p0 * (x-xc) ),  x < xc  (p0 > 0)
double* q0)       //   O  sampler  exp( yc + q0 * (x-xc) ),  x > xc  (q0 < 0)
{
    double  x1, x2, y1, y2, m1, m2;
    double  d, p, q, t;
    d = 1.0 - a * a;
    if( d < DBL_EPSILON )
        d = DBL_EPSILON;

// Set boundaries  ...(x1,y1)...(0,y0)...(x2,y2)...
// and slopes            m1    +ve,-ve      m2
    x1 = -gmv / a;
    y1 = x1 * (fpu - 0.5 * x1);
    m1 = fpu -

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -