Skip to content

Commit a8f1cdb

Browse files
committed
Adding winCsource folder to relevant folders
1 parent 354dbf6 commit a8f1cdb

31 files changed

+3958
-0
lines changed

diag/winCsource/bbprctile.c

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/* BBPRCTILE Bayesian bootstrap percentile
2+
*
3+
* Description:
4+
* bbp = bbprctile(x,p,B,w)
5+
* x = Mx1 matrix of data
6+
* p = Px1 or 1xP vector of percentiles
7+
* B = number of bootstrap replicates
8+
* w = Mx1 vector of weights
9+
10+
*
11+
* Copyright (C) 1998-2003 Aki Vehtari
12+
*
13+
* Last modified: 2011-09-07 10:36:44 EEST
14+
*
15+
*/
16+
17+
18+
/*
19+
*This software is distributed under the GNU General Public
20+
*License (version 3 or later); please refer to the file
21+
*License.txt, included with the software, for details.
22+
*
23+
*/
24+
25+
#include "mex.h"
26+
#include <math.h>
27+
28+
void mexFunction(const int nlhs, mxArray *plhs[],
29+
const int nrhs, const mxArray *prhs[])
30+
{
31+
if (nlhs > 1 )
32+
mexErrMsgTxt( "Too many output arguments.");
33+
34+
if (nrhs < 2 || nrhs > 4)
35+
mexErrMsgTxt( "Wrong number of input arguments." );
36+
37+
{
38+
double *x, *p, *w=NULL, *r, rsum, *bbp;
39+
mxArray *R, *P, *MN[2];
40+
const int *dims;
41+
int B, b, i, j, jj, m, n, plen;
42+
43+
dims = mxGetDimensions(prhs[0]);
44+
x = mxGetPr(prhs[0]);
45+
m = dims[0];
46+
n = dims[1];
47+
48+
dims = mxGetDimensions(prhs[1]);
49+
if (dims[0]>1 && dims[1]>1)
50+
mexErrMsgTxt("P must be a vector.");
51+
plen = dims[0]*dims[1];
52+
mexCallMATLAB(1, &P, 1, (mxArray **) &prhs[1], "sort");
53+
p = mxGetPr(P);
54+
for (j = 0; j < plen; j++) {
55+
p[j]=p[j]/100;
56+
}
57+
58+
if (nrhs>2) {
59+
dims = mxGetDimensions(prhs[2]);
60+
if (dims[0]>1 || dims[1]>1)
61+
mexErrMsgTxt("B must be a scalar.");
62+
B = mxGetScalar(prhs[2]);
63+
}
64+
else
65+
B = 1;
66+
67+
if (nrhs>3) {
68+
dims = mxGetDimensions(prhs[3]);
69+
if (dims[1]>1)
70+
mexErrMsgTxt("W must be a column vector.");
71+
if (dims[0]!=m)
72+
mexErrMsgTxt("W must be a same size as X.");
73+
w = mxGetPr(prhs[3]);
74+
}
75+
76+
plhs[0]=mxCreateDoubleMatrix(B, plen, mxREAL);
77+
bbp = mxGetPr(plhs[0]);
78+
79+
MN[0]=mxCreateDoubleScalar((double)m);
80+
MN[1]=mxCreateDoubleScalar(1.0);
81+
82+
if (w!=NULL) {
83+
for (b = 0; b < B; b++) {
84+
mexCallMATLAB(1,&R,2,MN,"rand");
85+
r = mxGetPr(R);
86+
jj=0;
87+
for (i = 0, rsum=0; i < m; i++) {
88+
r[i] = -log(r[i])*w[i];
89+
rsum += r[i];
90+
}
91+
r[0]=r[0]/rsum;
92+
for (j = 0; j < plen; j++) {
93+
if (r[0] >= p[j]) {
94+
bbp[b+j*B]=x[0];
95+
jj++;
96+
}
97+
else {
98+
break;
99+
}
100+
}
101+
for (i = 1; i < m-1; i++) {
102+
r[i]=r[i-1]+r[i]/rsum;
103+
for (j = jj; j < plen; j++) {
104+
if (r[i] >= p[j]) {
105+
bbp[b+j*B]=x[i-1]+(x[i]-x[i-1])*(p[j]-r[i-1])/(r[i]-r[i-1]);
106+
jj++;
107+
}
108+
else {
109+
break;
110+
}
111+
}
112+
}
113+
r[i]=1;
114+
for (j = jj; j < plen; j++) {
115+
if (r[i] >= p[j])
116+
bbp[b+j*B]=x[i-1]+(x[i]-x[i-1])*(p[j]-r[i-1])/(r[i]-r[i-1]);
117+
else {
118+
break;
119+
}
120+
}
121+
}
122+
}
123+
else {
124+
for (b = 0; b < B; b++) {
125+
mexCallMATLAB(1,&R,2,MN,"rand");
126+
r = mxGetPr(R);
127+
jj=0;
128+
for (i = 0, rsum=0; i < m; i++) {
129+
r[i] = -log(r[i]);
130+
rsum += r[i];
131+
}
132+
r[0]=r[0]/rsum;
133+
for (j = 0; j < plen; j++) {
134+
if (r[0] >= p[j]) {
135+
bbp[b+j*B]=x[0];
136+
jj++;
137+
}
138+
else
139+
break;
140+
}
141+
for (i = 1; i < m-1; i++) {
142+
r[i]=r[i-1]+r[i]/rsum;
143+
for (j = jj; j < plen; j++) {
144+
if (r[i] >= p[j]) {
145+
bbp[b+j*B]=x[i-1]+(x[i]-x[i-1])*(p[j]-r[i-1])/(r[i]-r[i-1]);
146+
jj++;
147+
}
148+
else
149+
break;
150+
}
151+
}
152+
r[i]=1;
153+
for (j = jj; j < plen; j++) {
154+
if (r[i] >= p[j])
155+
bbp[b+j*B]=x[i-1]+(x[i]-x[i-1])*(p[j]-r[i-1])/(r[i]-r[i-1]);
156+
else
157+
break;
158+
}
159+
160+
}
161+
}
162+
163+
mxDestroyArray(MN[0]);
164+
mxDestroyArray(MN[1]);
165+
mxDestroyArray(R);
166+
}
167+
168+
return;
169+
}

dist/winCsource/ars.c

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/* ARS.C - Procedure for performing Adaptive Rejection Sampling. */
2+
3+
/* Copyright (c) 1995-2003 by Carl Edward Rasmussen and Radford M. Neal
4+
*
5+
* Permission is granted for anyone to copy, use, modify, or distribute this
6+
* program and accompanying programs and documents for any purpose, provided
7+
* this copyright notice is retained and prominently displayed, along with
8+
* a note saying that the original programs are available from Radford Neal's
9+
* web page, and note is made of any changes made to the programs. The
10+
* programs and documents are distributed without any warranty, express or
11+
* implied. As the programs were written for research purposes only, they have
12+
* not been tested to the degree that would be advisable in any important
13+
* application. All use of these programs is entirely at the user's own risk.
14+
*/
15+
16+
17+
/* This module implements the "Adaptive Rejection Sampling" scheme due to
18+
* Gilks and Wild. See "Adaptive Rejection Sampling for Gibbs Sampling",
19+
* Applied Statistics, vol. 41, no. 2, pp. 337-348 (1992). This is not
20+
* the most sophisticated possible implementation of the method, however. */
21+
22+
23+
#include <math.h>
24+
#include <stdio.h>
25+
#include <stdlib.h>
26+
27+
#include "rand.h"
28+
#include "ars.h"
29+
30+
31+
#define MIN_DROP 0.1 /* minimum drop in log probability for initial points */
32+
#define TINY 1e-9 /* minimum tolerance for inserting new points */
33+
#define MAX_LIST 100 /* max number of segments in piecewise exponential */
34+
35+
struct segtype { double a; /* in the log domain, the piece wise... */
36+
double b; /* exponential is a piece wise linear: y=ax+b */
37+
double x; /* interior point in piece */
38+
double xmax; /* upper limit of this piece */
39+
double mass; /* the probability mass of this piece */
40+
struct segtype *prv; /* ptr to previous piece */
41+
struct segtype *nxt; }; /* ptr to next piece */
42+
43+
static struct segtype *root;
44+
45+
static double rpwed(struct segtype **);
46+
47+
48+
/* ADAPTIVE REJECTION SAMPLING PROCEDURE.
49+
*
50+
* The ars function returns a single point sampled at random from the univariate
51+
* distribution specified by the function logp, provided by the user. The
52+
* logp function takes a point as its first argument, and returns the log
53+
* of the probability density at that point, plus any arbitrary constant (not
54+
* depending on the point). The logp function takes two additional arguments,
55+
* the first a pointer to a place where it must store the derivative of the
56+
* log probability density, the second a pointer to additional information
57+
* describing the distribution, which is passed on unchanged from the last
58+
* argument of ars.
59+
*
60+
* The logp function passed MUST be log-concave. It is assumed that any real
61+
* number is legal as input to logp.
62+
*
63+
* The user must also supply an initial guess, "init", and a typical "scale"
64+
* of variation. It is not essential that these values be very accurate, but
65+
* performance will generally depend on their accuracy.
66+
*
67+
* The ars function first tries to locate points on either side of the mode;
68+
* the derivative must have the right sign and be non-negligible, and the drop
69+
* from the max. probability seen must be of at least moderate size to qualify.
70+
* Then a piece-wise exponential distribution is iteratively improved using
71+
* knowledge from rejected points, until a sample is accepted. At most MAX_LIST
72+
* pieces are introduced in the approximation. Before pieces are inserted
73+
* various checks are made in order to prevent numerical problems. If new points
74+
* don't qualify, the piece-wise exponential is simply not updated. A warning
75+
* will be issued (one time only) when 10000 rejections are exceeded */
76+
77+
double ars(
78+
double init, /* initial guess */
79+
double scale, /* guess for scale of variation in x */
80+
double (*logp)(double, double *, void *), /* function to sample from */
81+
void *extra /* any extra information to pass to logp() */
82+
)
83+
{
84+
struct segtype seg[MAX_LIST], *prv, *cur, *nxt;
85+
int i, no_seg = 2;
86+
static int warning = 0;
87+
double x, max, f, df;
88+
89+
root = &seg[0]; nxt = &seg[1];
90+
root->prv = NULL; root->nxt = nxt; nxt->prv = root; nxt->nxt = NULL;
91+
92+
x = init; f = logp(x, &df, extra); /* find point to the left of mode */
93+
max = f;
94+
while (df<TINY || f>max-MIN_DROP) {
95+
x -= scale+(init-x);
96+
f = logp(x, &df, extra);
97+
if (f>max) max = f;
98+
}
99+
root->x = x; root->a = df; root->b = f-x*df;
100+
101+
x = init; f = logp(x, &df, extra); /* find point to the right of mode */
102+
while (df>-TINY || f>max-MIN_DROP) {
103+
x += scale+(x-init);
104+
f = logp(x, &df, extra);
105+
if (f>max) max = f;
106+
}
107+
nxt->x = x; nxt->a = df; nxt->b = f-x*df;
108+
root->xmax = (nxt->b-root->b)/(root->a-nxt->a);
109+
110+
for (i=0; ; i++) { /* repeat until a point is accepted */
111+
112+
if (i==10000 && !(warning)) {
113+
fprintf(stderr, "WARNING: More than 10000 rejections in ars\n");
114+
warning = 1;
115+
}
116+
117+
cur = root; /* find max y-value; needed to avoid numerical problems */
118+
max = cur->a*cur->xmax+cur->b;
119+
while (cur = cur->nxt, cur->nxt)
120+
if ((x = cur->a*cur->xmax+cur->b) > max) max = x;
121+
122+
cur = root; /* compute masses */
123+
cur->mass = exp(cur->a*cur->xmax+cur->b-max)/cur->a;
124+
while (prv = cur, cur = cur->nxt, cur->nxt)
125+
cur->mass = (exp(cur->a*cur->xmax+cur->b-max)-
126+
exp(cur->a*prv->xmax+cur->b-max))/cur->a;
127+
cur->mass = -exp(cur->a*prv->xmax+cur->b-max)/cur->a;
128+
129+
x = rpwed(&cur); /* this is the new sample */
130+
f = logp(x, &df, extra);
131+
if (rand_uniform() <= exp(f-cur->a*x-cur->b)) return x; /* success! */
132+
133+
/* Now, insert a new piece in the piece-wise approximation if the situation is
134+
* appropriate. Eg, if we have enough memory, if the slope at the new x isn't
135+
* too small (the exponential distribution will degenerate), and if the slope
136+
* isn't too close to the slope of current, previous and next segment (or
137+
* which ever of these may exist), since this may cause numerical problems. */
138+
139+
if (no_seg < MAX_LIST && fabs(df) > TINY && fabs(df-cur->a) > TINY &&
140+
(!(cur->prv) || fabs(df-cur->prv->a) > TINY) &&
141+
(!(cur->nxt) || fabs(df-cur->nxt->a) > TINY)) {
142+
143+
if (x<cur->x) cur = cur->prv; /* now, insert *after* cur */
144+
prv = cur; cur = &seg[no_seg++]; cur->prv = prv;
145+
if (prv)
146+
{ cur->nxt = prv->nxt; prv->nxt = cur; }
147+
else
148+
{ cur->nxt = root; root = cur; }
149+
nxt = cur->nxt; if (nxt) nxt->prv = cur;
150+
cur->x = x; cur->a = df; cur->b = f-x*df;
151+
152+
if (prv) prv->xmax = (cur->b-prv->b)/(prv->a-cur->a);
153+
if (nxt) cur->xmax = (nxt->b-cur->b)/(cur->a-nxt->a);
154+
}
155+
}
156+
}
157+
158+
159+
/* Private function to sample from piece-wise exponential distribution. First a
160+
* piece under the piece-wise distribution is sampled at random. Then a random
161+
* sample is drawn from this piece. A pointer to the segment, or piece which
162+
* was used is returned in q, and the function returns the random sample. Care
163+
* is taken to avoid numerical over and underflow. */
164+
165+
static double rpwed(struct segtype **q)
166+
{
167+
double mass = 0.0, t, u;
168+
169+
*q = root; while (*q) { mass += (*q)->mass; *q = (*q)->nxt; }
170+
t = mass*rand_uniform();
171+
*q = root; while ((*q)->nxt && ((t -= (*q)->mass) >= 0.0)) *q = (*q)->nxt;
172+
173+
u = rand_uniopen();
174+
if ((*q)->prv == NULL)
175+
return (*q)->xmax+log(u)/(*q)->a;
176+
if ((*q)->nxt == NULL)
177+
return (*q)->prv->xmax+log(u)/(*q)->a;
178+
t = log(u+(1.0-u)*exp(fabs((*q)->a)*((*q)->prv->xmax-(*q)->xmax)))/(*q)->a;
179+
return ((*q)->a > 0) ? (*q)->xmax+t : (*q)->prv->xmax+t;
180+
}

dist/winCsource/ars.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* ARS.H - Interface to Adaptive Rejection Sampling procedure. */
2+
3+
4+
/* Copyright (c) 1995-2003 by Carl Edward Rasmussen and Radford M. Neal
5+
*
6+
* Permission is granted for anyone to copy, use, modify, or distribute this
7+
* program and accompanying programs and documents for any purpose, provided
8+
* this copyright notice is retained and prominently displayed, along with
9+
* a note saying that the original programs are available from Radford Neal's
10+
* web page, and note is made of any changes made to the programs. The
11+
* programs and documents are distributed without any warranty, express or
12+
* implied. As the programs were written for research purposes only, they have
13+
* not been tested to the degree that would be advisable in any important
14+
* application. All use of these programs is entirely at the user's own risk.
15+
*/
16+
17+
double ars(double, double, double (*)(double, double *, void *), void *);

0 commit comments

Comments
 (0)