https://github.com/MoorjaniLab/DATES_v4010
Revision b2c18138af9b2bced70174b9efa651f85f1d6507 authored by MoorjaniLab on 06 May 2022, 19:16:07 UTC, committed by GitHub on 06 May 2022, 19:16:07 UTC
1 parent 754adef
Tip revision: b2c18138af9b2bced70174b9efa651f85f1d6507 authored by MoorjaniLab on 06 May 2022, 19:16:07 UTC
Update README.md
Update README.md
Tip revision: b2c1813
qpsubs.c
#include "qpsubs.h"
extern int fancynorm, verbose, plotmode, outnum;
extern FILE *fstdetails;
static Indiv **indm;
static double quartile = -1.0;
static int jackweight = YES;
// .05 will trim jackknife stats
static void wjackestx (double *est, double *sig, double mean, double *jmean,
double *jwt, int g);
static void wjackvestx (double *vest, double *var, int d, double *mean,
double **jmean, double *jwt, int g);
void printnorm (double *a, int n);
static int pubjack = NO;
static void calcndinbreed (int *c1, int *c2, double *pen, double *ped);
static void calchetinbreed (int *c1, double *pen, double *ped);
static int inbreed = NO;
static int allsnpsmode = NO;
static double **aacnts =
NULL, **bbcnts, *aafreq, *ttnum, *hest, *htest, *aaxadd;
static char **aalist;
static int aanum = -1;
void loadaa (SNP * cupt, int *xindex, int *xtypes, int nrows, int numeg);
void destroyaa ();
void
printsc (int tpat[3][4], double tscore[3], char **eglist, double ymin)
{
int a, b, c, d;
int *tp, k;
tp = tpat[0];
printf ("qscore: ");
a = tp[0];
printf ("%15s ", eglist[a]);
a = tp[1];
printf ("%15s ", eglist[a]);
printf (" ");
a = tp[2];
printf ("%15s ", eglist[a]);
a = tp[3];
printf ("%15s ", eglist[a]);
for (k = 0; k < 3; k++) {
tp = tpat[k];
printf ("%2d ", tp[0]);
printf ("%2d ", tp[1]);
printf (" ");
printf ("%2d ", tp[2]);
printf ("%2d ", tp[3]);
printf ("%9.3f", tscore[k]);
}
printf (" %9.3f\n", ymin);
printnl ();
}
void
xcopy (int rp[4], int a, int b, int c, int d)
{
rp[0] = a;
rp[1] = b;
rp[2] = c;
rp[3] = d;
}
void
setallsnpsmode (int mode)
{
allsnpsmode = mode;
}
void
settsc (int tpat[3][4], double tscore[3], int rpat[3][4], double rscore[3])
/// process rscore and return scores in tscore with tscore[0] best
{
double ww[3], w2[3], y;
double xmax, xmin;
int indx[3], i, k;
vvt (ww, rscore, rscore, 3);
vmaxmin (ww, 3, &xmax, &xmin);
vsp (ww, ww, -xmin, 3);
copyarr (ww, w2, 3);
vst (ww, ww, -1.0, 3);
sortit (w2, indx, 3);
y = w2[1]; // second best score
vsp (ww, ww, y, 3);
for (i = 0; i < 3; i++) {
k = indx[i];
if (i == 0)
y = rscore[k];
tscore[i] = ww[k];
copyiarr (rpat[k], tpat[i], 4);
}
}
void
getpdata (int *rawcol, double *pm, double *pn, int *xtypes, int nrows,
int numeg)
{
int *ytypes, n = 0;
int i, k, t, g;
double *data, y;
vzero (pm, numeg);
vzero (pn, numeg);
ZALLOC (ytypes, nrows, int);
ZALLOC (data, nrows, double);
for (k = 0; k < nrows; ++k) {
g = rawcol[k];
t = xtypes[k];
if (g < 0)
continue;
if (t < 0)
continue;
data[n] = g;
ytypes[n] = t;
++n;
}
if (n <= 1) {
free (ytypes);
free (data);
return;
}
y = asum (data, n) / (double) n;
// vsp(data, data, -y, n) ;
y = 0.5 * y;
y = y * (1.0 - y);
if (y < .001) {
free (ytypes);
free (data);
return;
}
vst (data, data, 1.0 / sqrt (y), n);
for (i = 0; i < n; i++) {
t = ytypes[i];
if (t < 0)
continue;
if (t >= numeg)
continue;
pm[t] += data[i];
pn[t] += 1.0;
}
vsp (pn, pn, 1.0e-8, numeg);
vvd (pm, pm, pn, numeg);
free (ytypes);
free (data);
}
void
gethscore (double *hscore, double *scores,
int a, int b, int c, int d, int numeg)
{
hscore[0] = qhdiff (scores, a, b, c, d, numeg);
hscore[1] = qhdiff (scores, a, b, c, d, numeg);
hscore[2] = qhdiff (scores, a, b, c, d, numeg);
}
void
getrscore (double *rscore, double *rho, double **zz,
int ncols, int a, int b, int c, int d, int numeg, int *blabels,
int nblocks)
{
rscore[0] = qcorr (zz, &rho[0], ncols, a, b, c, d, numeg, blabels, nblocks);
rscore[1] = qcorr (zz, &rho[1], ncols, a, c, b, d, numeg, blabels, nblocks);
rscore[2] = qcorr (zz, &rho[2], ncols, a, d, b, c, numeg, blabels, nblocks);
}
double
qhdiff (double *scores, int a, int b, int c, int d, int numeg)
{
double tt[4], xmax, xmin;
tt[0] = scores[a * numeg + c];
tt[1] = scores[a * numeg + d];
tt[2] = scores[b * numeg + c];
tt[3] = scores[b * numeg + d];
vmaxmin (tt, 4, &xmax, &xmin);
return -(xmax - xmin);
}
double
qcorr (double **zz, double *rho, int ncols, int a, int b, int c, int d,
int numeg, int *blabels, int nblocks)
{
double *z1, *z2, y, xrho, xsig;
int u, v;
u = MIN (a, b);
v = MAX (a, b);
z1 = zz[u * numeg + v];
u = MIN (c, d);
v = MAX (c, d);
z2 = zz[u * numeg + v];
corrwjack (&xrho, &xsig, z1, z2, ncols, blabels, nblocks);
*rho = xrho;
y = xrho / xsig;
return y;
}
int
loadindx (Indiv ** xindlist, int *xindex, Indiv ** indivmarkers,
int numindivs)
{
int i, n = 0;
Indiv *indx;
for (i = 0; i < numindivs; i++) {
indx = indivmarkers[i];
if (indx->ignore)
continue;
if (indx->affstatus == NO)
continue;
xindex[n] = i;
xindlist[n] = indx;
++n;
}
return n;
}
int
loadsnpx (SNP ** xsnplist, SNP ** snpmarkers, int numsnps,
Indiv ** indivmarkers)
{
int i, n = 0;
SNP *cupt;
for (i = 0; i < numsnps; i++) {
cupt = snpmarkers[i];
cupt->tagnumber = -1;
if (cupt->ignore)
continue;
if (numvalidgt (indivmarkers, cupt) == 0)
continue;
xsnplist[n] = cupt;
cupt->tagnumber = n;
++n;
}
return n;
}
void
getrawcol (int *rawcol, SNP * cupt, int *xindex, int nrows)
{
int t, j;
for (j = 0; j < nrows; j++) {
t = xindex[j];
rawcol[j] = getgtypes (cupt, t);
// if (verbose) printf("www %d %d %d\n", j, t, rawcol[j]) ;
}
}
void
getrawcolx (int **cc, SNP * cupt, int *xindex, int nrows, Indiv ** indm)
{
int t, j, g, tt;
int *gg;
Indiv *indx;
static int ncall = 0;
++ncall;
// tt = strcmp(cupt -> ID, "rs10914979") ;
tt = -1;
for (j = 0; j < nrows; j++) {
t = xindex[j];
gg = cc[j];
ivclear (gg, -1, 2);
g = getgtypes (cupt, t);
if (tt == 0)
printf ("zzcolx %d %d %d\n", j, t, g);
if (ncall == -1) {
printf ("zzindx2: %s\n", indm[230]->egroup);
printf ("zz1 %d %d %d\n", j, t, g);
indx = indm[t];
printf ("yy2 %20s %20s %20s %d %d %d\n", cupt->ID, indx->ID,
indx->egroup, j, t, g);
}
if (g < 0)
continue;
gg[0] = g;
gg[1] = 2 - g;
if (cupt->chrom != 23)
continue;
if (indm[t]->gender != 'M')
continue;
if (g == 1) {
ivclear (gg, -1, 2);
continue;
}
g = g / 2;
gg[0] = g;
gg[1] = 1 - g;
}
}
void
getcolx (double *xcol, SNP * cupt, int *xindex, int nrows, int col,
double *xmean, double *xfancy)
// side effect set xmean xfancy
{
Indiv *indx;
int j, n, g, t;
double y, pmean, p;
int *rawcol;
ZALLOC (rawcol, nrows, int);
n = cupt->ngtypes;
if (n < nrows)
fatalx ("bad snp: %s %d\n", cupt->ID, n);
getrawcol (rawcol, cupt, xindex, nrows);
floatit (xcol, rawcol, nrows);
vadjust (xcol, nrows, &pmean);
if (fancynorm) {
p = 0.5 * pmean; // autosomes
y = p * (1.0 - p);
if (y <= 0.0)
return;
y = 1.0 / sqrt (y);
vst (xcol, xcol, y, nrows);
}
else
y = 1.0;
if (xmean != NULL) {
xmean[col] = pmean * y;
xfancy[col] = y;
}
free (rawcol);
}
void
loadxdataind (double *xrow, SNP ** snplist, int ind, int ncols)
{
SNP *cupt;
Indiv *indx;
int i, j, k, n, g;
for (i = 0; i < ncols; i++) {
cupt = snplist[i];
g = getgtypes (cupt, ind);
xrow[i] = (double) g;
}
}
void
fixxrow (double *xrow, double *xmean, double *xfancy, int len)
{
int i;
vvt (xrow, xrow, xfancy, len);
for (i = 0; i < len; i++) {
if (xrow[i] < -0.1)
xrow[i] = 0.0;
else
xrow[i] -= xmean[i];
}
}
void
dofancy (double *cc, int n, double *fancy)
{
int i, t, nmiss = 0;
int top, bot;
double p, yvar, y;
top = bot = 0;
for (i = 0; i < n; i++) {
t = nnint (cc[i]);
if (t < 0) {
++nmiss;
continue;
}
top += t;
bot += 2;
}
if (bot == 0)
return;
if (top == 0)
return;
if (top == bot)
return;
p = (double) top / ((double) bot);
yvar = p * (1.0 - p);
y = 1.0 / sqrt (yvar);
vst (cc, cc, y, n);
*fancy = y;
}
int
vadjust (double *cc, int n, double *pmean)
/* take off mean force missing to zero */
{
double ynum, ysum, y, ymean;
int i, nmiss = 0;
ynum = ysum = 0.0;
for (i = 0; i < n; i++) {
y = cc[i];
if (y < 0.0) {
++nmiss;
continue;
}
++ynum;
ysum += y;
}
if (ynum == 0.0)
fatalx ("logic bug all missing\n");
ymean = ysum / ynum;
for (i = 0; i < n; i++) {
y = cc[i];
if (y < 0.0)
cc[i] = 0.0;
else
cc[i] -= ymean;
}
if (pmean != NULL)
*pmean = ymean;
return nmiss;
}
double
yll (double x1, double x2, double xlen)
{
double m1, m2, var;
if (xlen < 1.5)
return 0.0;
m1 = x1 / xlen;
m2 = x2 / xlen;
var = m2 - m1 * m1;
if (var <= 0.0)
fatalx ("bad yll\n");
return -0.5 * xlen * log (var);
}
void
calcmean (double *wmean, double *vec, int len, int *xtypes, int numeg)
{
int i, k;
double y1;
double *w0, *popsize;
ZALLOC (w0, len, double);
ZALLOC (popsize, numeg, double);
y1 = asum (vec, len) / (double) len; // mean
vsp (w0, vec, -y1, len);
for (i = 0; i < len; i++) {
k = xtypes[i];
++popsize[k];
wmean[k] += w0[i];
}
vsp (popsize, popsize, 1.0e-12, numeg);
vvd (wmean, wmean, popsize, numeg);
free (w0);
free (popsize);
}
void
setmiss (SNP ** snpm, int numsnps)
{
SNP *cupt;
int i, j, t, n, tot;
for (i = 0; i < numsnps; i++) {
cupt = snpm[i];
n = cupt->ngtypes;
if (n <= 0)
continue;
tot = 0;
for (j = 0; j < n; j++) {
if (getgtypes (cupt, j) >= 0) {
t = 1;
}
else {
t = 0;
}
putgtypes (cupt, j, t);
tot += t;
}
if (verbose)
printf ("Valids: %s %d\n", cupt->ID, tot);
}
}
void
setfvecs (double *fvecs, double *evecs, int nrows, int numeigs)
// plotmode each eigenvector min 0 max 1
{
double *w;
double xmax, xmin;
int i, j;
ZALLOC (w, nrows, double);
for (j = 0; j < numeigs; j++) {
copyarr (evecs + j * nrows, w, nrows);
if (plotmode == NO) {
vst (fvecs + j * nrows, w, 10.0, nrows);
continue;
}
copyarr (w, fvecs + j * nrows, nrows);
}
free (w);
}
void
countpopsx (int ***counts, SNP ** xsnplist, Indiv ** xindlist, int *xindex,
int *xtypes, int nrows, int ncols)
{
int col, i, g1, g2, g, k1;
SNP *cupt;
int *rawcol;
int ismale;
ZALLOC (rawcol, nrows, int);
for (col = 0; col < ncols; ++col) {
cupt = xsnplist[col];
getrawcol (rawcol, cupt, xindex, nrows);
for (i = 0; i < nrows; i++) {
ismale = NO;
if (xindlist[i]->gender == 'M')
ismale = YES;
g = rawcol[i];
k1 = xtypes[i];
if (k1 < 0)
continue;
if (g < 0)
continue;
if (ismale) {
if (g == 1)
continue;
g1 = g / 2;
++counts[col][k1][g1];
continue;
}
g1 = 0;
if (g > 0)
g1 = 1;
g2 = g - g1;
if (g1 < 0)
fatalx ("bug\n");
if (g2 < 0)
fatalx ("bug\n");
if (g1 > 1)
fatalx ("bug\n");
if (g2 > 1)
fatalx ("bug\n");
++counts[col][k1][g1];
++counts[col][k1][g2];
}
}
free (rawcol);
}
void
countpopsr (int ***counts, SNP ** xsnplist, int *xindex, int *xtypes,
int nrows, int ncols)
// counts is int [ncols][npops][2]
// pick 1 random allele from each sample
{
int col, i, g1, g2, g, k1;
SNP *cupt;
int *rawcol;
ZALLOC (rawcol, nrows, int);
for (col = 0; col < ncols; ++col) {
cupt = xsnplist[col];
getrawcol (rawcol, cupt, xindex, nrows);
for (i = 0; i < nrows; i++) {
g = rawcol[i];
k1 = xtypes[i];
if (k1 < 0)
continue;
if (g < 0)
continue;
g1 = g / 2;
if (g == 1)
g1 = ranmod (2);
++counts[col][k1][g1];
}
}
free (rawcol);
}
void
countpops (int ***counts, SNP ** xsnplist, int *xindex, int *xtypes,
int nrows, int ncols)
// countpops is int [ncols][npops][2]
{
int col, i, g1, g2, g, k1;
SNP *cupt;
int *rawcol;
ZALLOC (rawcol, nrows, int);
for (col = 0; col < ncols; ++col) {
cupt = xsnplist[col];
getrawcol (rawcol, cupt, xindex, nrows);
for (i = 0; i < nrows; i++) {
g = rawcol[i];
k1 = xtypes[i];
if (k1 < 0)
continue;
if (g < 0)
continue;
g1 = 0;
if (g > 0)
g1 = 1;
g2 = g - g1;
if (g1 < 0)
fatalx ("bug\n");
if (g2 < 0)
fatalx ("bug\n");
if (g1 > 1)
fatalx ("bug\n");
if (g2 > 1)
fatalx ("bug\n");
++counts[col][k1][g1];
++counts[col][k1][g2];
}
}
free (rawcol);
}
// setidmat used to scale
void
fixrho (double *a, int n)
// turn a into correlation matrix
{
double *d, *tt, y;
int i;
ZALLOC (d, n, double);
ZALLOC (tt, n * n, double);
getdiag (d, a, n);
vsqrt (d, d, n);
addouter (tt, d, n);
vvd (a, a, tt, n * n);
free (d);
free (tt);
}
void
printdiag (double *a, int n)
{
double *d, *tt, y;
int i;
ZALLOC (d, n, double);
getdiag (d, a, n);
y = asum (d, n) / (double) n;
for (i = 0; i < n; i++) {
printf ("diag: %9.3f\n", d[i] / y);
}
free (d);
abort ();
}
int
ridoutlier (double *evecs, int n, int neigs, double thresh, int *badlist)
{
/* badlist contains list of outliers */
double *ww, y1, y2;
int *vbad;
int i, j;
int nbad = 0;
ZALLOC (ww, n, double);
ZALLOC (vbad, n, int);
for (i = 0; i < neigs; ++i) {
copyarr (evecs + i * n, ww, n);
y1 = asum (ww, n) / (double) n;
vsp (ww, ww, -y1, n);
y2 = asum2 (ww, n) / (double) n;
y2 = sqrt (y2);
vst (ww, ww, 1.0 / y2, n);
for (j = 0; j < n; j++) {
if (fabs (ww[j]) > thresh) {
vbad[j] = 1;
}
}
}
for (j = 0; j < n; j++) {
if (vbad[j] == 1) {
badlist[nbad] = j;
++nbad;
}
}
free (ww);
free (vbad);
return nbad;
}
void
addoutersym (double *X, double *v, int n)
{
int i, j;
for (i = 0; i < n; i++) {
for (j = i; j < n; j++) {
X[i * n + j] += v[i] * v[j];
}
}
}
void
symit (double *X, int n)
{
int i, j;
for (i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
X[j * n + i] = X[i * n + j];
}
}
}
double
divcol (double *estn, double *estd, SNP * cupt,
int *xindex, int *xtypes, int nrows, int type1, int type2)
/* heterozygosity for 2 pops */
{
int c1[2], c2[2], *cc;
int *rawcol;
int k, g, i;
double ya, yb, yaa, ybb, p1, p2, en, ed;
double z, zz, h1, h2, yt;
ZALLOC (rawcol, nrows, int);
getrawcol (rawcol, cupt, xindex, nrows);
ivzero (c1, 2);
ivzero (c2, 2);
for (i = 0; i < nrows; i++) {
k = xtypes[i];
cc = NULL;
if (k == type1)
cc = c1;
if (k == type2)
cc = c2;
if (cc == NULL)
continue;
g = rawcol[i];
if (g < 0)
continue;
cc[0] += g;
cc[1] += 2 - g;
}
ya = c1[0];
yb = c1[1];
yaa = c2[0];
ybb = c2[1];
z = ya + yb;
zz = yaa + ybb;
if ((z < 0.1) || (zz < 0.1)) {
*estn = 0.0;
*estd = -1.0; /* no data */
free (rawcol);
return 0.0;
}
en = ya * ybb + yb * yaa;
ed = z * zz;
*estn = en;
*estd = ed;
free (rawcol);
return z + zz;
}
void
f3y (double *estn, SNP * cupt,
int *xindex, int *xtypes, int nrows, int type1, int type2, int type3)
{
int c1[2], c2[2], c3[2], *cc;
int *rawcol;
int k, g, i, a, b;
double ya, yb, yaa, ybb, p1, p2, p3, en, ed;
double z, zz, h1, h2, yt;
double ywt;
ZALLOC (rawcol, nrows, int);
getrawcol (rawcol, cupt, xindex, nrows);
ivzero (c1, 2);
ivzero (c2, 2);
ivzero (c3, 2);
for (i = 0; i < nrows; i++) {
k = xtypes[i];
cc = NULL;
if (k == type1)
cc = c1;
if (k == type2)
cc = c2;
if (k == type3)
cc = c3;
if (cc == NULL)
continue;
g = rawcol[i];
if (g < 0)
continue;
cc[0] += g;
cc[1] += 2 - g;
}
ya = a = c1[0];
yb = b = c1[1];
z = ya + yb;
yt = ya + yb;
p1 = ya / yt;
h1 = ya * yb / (yt * (yt - 1.0));
yaa = c2[0];
ybb = c2[1];
zz = yaa + ybb;
yt = yaa + ybb;
p2 = yaa / yt;
h2 = yaa * ybb / (yt * (yt - 1.0));
yaa = c3[0];
ybb = c3[1];
yt = yaa + ybb;
p3 = yaa / yt;
en = (p1 - p2) * (p1 - p3);
en -= h1 / z;
if (type2 == type3)
en -= h2 / zz;
*estn = en;
free (rawcol);
}
void
f2scz (double *estn, double *estd, SNP * cupt, Indiv ** indm,
int *xindex, int *xtypes, int nrows, int type1, int type2, int type3)
// processes X chromosome correctly
{
int c1[2], c2[2], c3[2], c4[2], *cc;
int *rawcol;
int k, g, i, a, b;
double ya, yb, yaa, ybb, p1, p2, p3, p4, en, ed;
double z, zz, h1, h2, h3, yt;
double z2, z3;
double ywt;
int **ccc, *ccpt[3];
int maxeg;
*estn = 0;
*estd = -1;
p1 = aafreq[type1];
h1 = hest[type1];
p2 = aafreq[type2];
p3 = aafreq[type3];
// if (h1 == 0.0) return ; dzeromode WRONG
if (p1 < -1.0)
return;
if (p2 < -1.0)
return;
if (p3 < -1.0)
return;
if (p3 < -1.0)
return;
if (hest[type2] < -100)
return;
if (hest[type3] < -100)
return;
en = (p2 - p3) * (p2 - p3);
en += aaxadd[type2];
en += aaxadd[type3];
en -= htest[type2];
en -= htest[type3];
if (isnan (en))
fatalx ("f2sc bug\n");
*estn = en;
*estd = 2.0 * h1;
}
void
f2sc (double *estn, double *estd, SNP * cupt, Indiv ** indm,
int *xindex, int *xtypes, int nrows, int type1, int type2, int type3)
// processes X chromosome correctly
{
int c1[2], c2[2], c3[2], c4[2], *cc;
int *rawcol;
int k, g, i, a, b;
double ya, yb, yaa, ybb, p1, p2, p3, p4, en, ed;
double z, zz, h1, h2, h3, yt;
double z2, z3;
double ywt;
int **ccc, *ccpt[3];
int maxeg;
maxeg = MAX (type1, type2);
maxeg = MAX (maxeg, type3) + 1;
loadaa (cupt, xindex, xtypes, nrows, maxeg);
f2scz (estn, estd, cupt, indm, xindex, xtypes, nrows, type1, type2, type3);
}
void
getcntpop (int *cx0, int *cx1, SNP * cupt, Indiv ** indm, int *xindex,
int *xtypes, int nrows, int type)
{
int **ccc, n0, n1, g, k, i;
ccc = initarray_2Dint (nrows, 2, 0);
getrawcolx (ccc, cupt, xindex, nrows, indm);
for (i = 0; i < nrows; i++) {
k = xtypes[i];
if (k != type)
continue;
g = ccc[i][0];
if (g < 0)
continue;
n0 += g;
g = ccc[i][1];
n1 += g;
}
*cx0 = n0;
*cx1 = n1;
free2Dint (&ccc, nrows);
}
int
f3scz (double *estn, double *estd, SNP * cupt, Indiv ** indm,
int *xindex, int *xtypes, int nrows, int type1, int type2, int type3)
// processes X chromosome correctly
{
int k, g, i, a, b;
double y, ya, yb, yaa, ybb, p1, p2, p3, p4, en, ed;
double z, zz, h1, yt;
double ywt;
int maxeg, ispoly ;
*estn = 0;
*estd = -1;
p1 = aafreq[type1];
h1 = hest[type1];
p2 = aafreq[type2];
p3 = aafreq[type3];
ispoly = 1 ;
y = (p1+p2+p3)/3.0 ;
if (y<.0001) ispoly = 0 ;
if (y>.9999) ispoly = 0 ;
// if (h1 == 0.0) return ;
if (p1 < -1.0)
return -1;
if (p2 < -1.0)
return -1;
if (p3 < -1.0)
return -1;
if (h1 < -100.0)
return -1;
en = (p1 - p2) * (p1 - p3);
en += aaxadd[type1];
en -= htest[type1];
if (isnan (en))
fatalx ("f3 bug\n");
*estn = en;
*estd = 2.0 * h1;
return ispoly ;
}
int
f3sc (double *estn, double *estd, SNP * cupt, Indiv ** indm,
int *xindex, int *xtypes, int nrows, int type1, int type2, int type3)
// processes X chromosome correctly
{
int k, g, i, a, b;
double ya, yb, yaa, ybb, p1, p2, p3, p4, en, ed;
double z, zz, h1, yt;
double ywt;
int maxeg;
maxeg = MAX (type1, type2);
maxeg = MAX (maxeg, type3) + 1;
loadaa (cupt, xindex, xtypes, nrows, maxeg);
return f3scz (estn, estd, cupt, indm, xindex, xtypes, nrows, type1, type2, type3);
}
void
finfo (double *xn, double *xm, double *xh, int type)
{
// f3sc or similar called first
*xn = ttnum[type]; // number of samples
*xm = aafreq[type]; // mean
*xh = hest[type]; // 1/2 het rate
}
void
f4yx (double *estn, SNP * cupt, Indiv ** indm,
int *xindex, int *xtypes, int nrows, int type1, int type2, int type3,
int type4)
// processes X chromosome correctly
{
int c1[2], c2[2], c3[2], c4[2], *cc;
int *rawcol;
int k, g, i, a, b;
double ya, yb, yaa, ybb, p1, p2, p3, p4, en, ed;
double z, zz, h1, h2, yt;
double ywt;
int **ccc;
ccc = initarray_2Dint (nrows, 2, 0);
getrawcolx (ccc, cupt, xindex, nrows, indm);
ivzero (c1, 2);
ivzero (c2, 2);
ivzero (c3, 2);
ivzero (c4, 2);
for (i = 0; i < nrows; i++) {
k = xtypes[i];
cc = NULL;
if (k == type1)
cc = c1;
if (k == type2)
cc = c2;
if (k == type3)
cc = c3;
if (k == type4)
cc = c4;
if (cc == NULL)
continue;
g = ccc[i][0];
if (g < 0)
continue;
cc[0] += g;
g = ccc[i][1];
cc[1] += g;
}
ya = a = c1[0];
yb = b = c1[1];
z = ya + yb;
yt = ya + yb;
p1 = ya / yt;
h1 = ya * yb / (yt * (yt - 1.0));
yaa = c2[0];
ybb = c2[1];
yt = yaa + ybb;
p2 = yaa / yt;
yaa = c3[0];
ybb = c3[1];
yt = yaa + ybb;
p3 = yaa / yt;
yaa = c4[0];
ybb = c4[1];
yt = yaa + ybb;
p4 = yaa / yt;
en = (p1 - p2) * (p3 - p4);
*estn = en;
free2Dint (&ccc, nrows);
}
void
f4y (double *estn, SNP * cupt,
int *xindex, int *xtypes, int nrows, int type1, int type2, int type3,
int type4)
{
int c1[2], c2[2], c3[2], c4[2], *cc;
int *rawcol;
int k, g, i, a, b;
double ya, yb, yaa, ybb, p1, p2, p3, p4, en, ed;
double z, zz, h1, h2, yt;
double ywt;
ZALLOC (rawcol, nrows, int);
getrawcol (rawcol, cupt, xindex, nrows);
ivzero (c1, 2);
ivzero (c2, 2);
ivzero (c3, 2);
ivzero (c4, 2);
for (i = 0; i < nrows; i++) {
k = xtypes[i];
cc = NULL;
if (k == type1)
cc = c1;
if (k == type2)
cc = c2;
if (k == type3)
cc = c3;
if (k == type4)
cc = c4;
if (cc == NULL)
continue;
g = rawcol[i];
if (g < 0)
continue;
cc[0] += g;
cc[1] += 2 - g;
}
ya = a = c1[0];
yb = b = c1[1];
z = ya + yb;
yt = ya + yb;
p1 = ya / yt;
h1 = ya * yb / (yt * (yt - 1.0));
yaa = c2[0];
ybb = c2[1];
yt = yaa + ybb;
p2 = yaa / yt;
yaa = c3[0];
ybb = c3[1];
yt = yaa + ybb;
p3 = yaa / yt;
yaa = c4[0];
ybb = c4[1];
yt = yaa + ybb;
p4 = yaa / yt;
en = (p1 - p2) * (p3 - p4);
*estn = en;
free (rawcol);
}
void
fstcolyy (double *estnmat, double *estdmat, SNP * cupt,
int *xindex, int *xtypes, int nrows, int numeg)
/**
NP style n, d estimation for fst No ascertainment
like fstcoly but a matrix of populations so data is only accessed once
inbreed option
*/
{
int *c1, *c2, *cc;
int *rawcol;
int k, g, i, j, a, b;
double ya, yb, yaa, ybb, p1, p2, en, ed;
double z, zz, h1, h2, yt;
double ywt;
int **ccc, *gg, **ddd;
static int ncall = 0;
++ncall;
loadaa (cupt, xindex, xtypes, nrows, numeg);
vzero (estnmat, numeg * numeg);
vclear (estdmat, -1.0, numeg * numeg);
for (a = 0; a < numeg; a++) {
estdmat[a * numeg + a] = 0.0;
}
ywt = 1.0;
for (i = 0; i < numeg; i++) {
for (j = i + 1; j < numeg; j++) {
if (aafreq[i] < -1.0)
continue;
if (aafreq[j] < -1.0)
continue;
if (hest[i] < -100.0)
continue;
if (hest[j] < -100.0)
continue;
ya = aafreq[i];
ya = aafreq[i];
yb = aafreq[j];
en = (ya - yb) * (ya - yb);
en += aaxadd[i];
en += aaxadd[j];
en -= htest[i];
en -= htest[j];
ed = en + hest[i] + hest[j];
if (ed < 0.0)
fatalx ("logic bug\n");
estnmat[i * numeg + j] = estnmat[j * numeg + i] = en * ywt;
estdmat[i * numeg + j] = estdmat[j * numeg + i] = ed * ywt;
}
}
}
double
fstcoly (double *estn, double *estd, SNP * cupt,
int *xindex, int *xtypes, int nrows, int type1, int type2)
/** NP style n, d estimation for fst No ascertainment */
{
int c1[2], c2[2], *cc;
int *rawcol;
int k, g, i, a, b;
double ya, yb, yaa, ybb, p1, p2, en, ed;
double z, zz, h1, h2, yt;
double ywt;
int **ccc, *gg;
static int ncall = 0;
++ncall;
ccc = initarray_2Dint (nrows, 2, 0);
if (indm == NULL) {
ZALLOC (rawcol, nrows, int);
getrawcol (rawcol, cupt, xindex, nrows);
for (a = 0; a < nrows; a++) {
g = rawcol[a];
ccc[a][0] = g;
ccc[a][1] = 2 - g;
}
free (rawcol);
}
else {
getrawcolx (ccc, cupt, xindex, nrows, indm);
}
ivzero (c1, 2);
ivzero (c2, 2);
for (i = 0; i < nrows; i++) {
k = xtypes[i];
cc = NULL;
gg = ccc[i];
if (ncall == -11) {
printf ("zzindx1: %s\n", indm[230]->egroup);
printf ("zz2 %d %d ", type1, type2);
printf ("%3d %d %3d %3d\n", i, k, gg[0], gg[1]);
}
if (k == type1)
cc = c1;
if (k == type2)
cc = c2;
if (cc == NULL)
continue;
g = gg[0];
if (g < 0)
continue;
ivvp (cc, cc, gg, 2);
}
ya = a = c1[0];
yb = b = c1[1];
yaa = c2[0];
ybb = c2[1];
zz = yaa + ybb;
z = ya + yb;
if ((z < 1.5) || (zz < 1.5)) {
*estn = 0.0;
*estd = -1.0; /* no data in column */
free2Dint (&ccc, nrows);
return 0.0;
}
ywt = ya * yb / (z * (z - 1.0)); // z must be at least 2
ywt = 1.0;
z = ya + yb;
yt = ya + yb;
p1 = ya / yt;
h1 = ya * yb / (yt * (yt - 1.0)); // 2 h1 is heterozygosity
yt = yaa + ybb;
p2 = yaa / yt;
h2 = yaa * ybb / (yt * (yt - 1.0));
en = (p1 - p2) * (p1 - p2);
en -= h1 / z;
en -= h2 / zz;
ed = en;
ed += h1;
ed += h2;
if (ed < 0.0)
fatalx ("logic bug\n");
*estn = en * ywt;
*estd = ed * ywt;
/**
printf("zz %20s %2d %2d ", cupt ->ID, type1, type2) ;
printf("%3d %3d ", c1[0], c1[1]) ;
printf("%3d %3d ", c2[0], c2[1]) ;
printf(" %9.3f %9.3f", *estn, *estd) ;
printnl() ;
*/
free2Dint (&ccc, nrows);
return z + zz;
}
void
setplimit (Indiv ** indivmarkers, int numindivs,
char **eglist, int numeg, int plimit)
{
int *indnums;
int *psize;
int i, k, kk;
Indiv *indx;
ZALLOC (indnums, numindivs, int);
ZALLOC (psize, numeg, int);
idperm (indnums, numindivs);
ranperm (indnums, numindivs);
for (i = 0; i < numindivs; i++) {
k = indnums[i];
indx = indivmarkers[k];
if (indx->ignore)
continue;
kk = indxindex (eglist, numeg, indx->egroup);
if (kk < 0)
continue;
++psize[kk];
if (psize[kk] > plimit)
indx->ignore = YES;
}
free (psize);
free (indnums);
}
void
dohzg (double *top, double *bot, SNP ** xsnplist, int *xindex, int *xtypes,
int nrows, int ncols, int numeg)
{
int t1, t2;
int c1[2], c2[2], *cc;
int *rawcol, *popall, *pop0, *pop1;
int k, g, i, col, j;
double ya, yb, y;
double *xtop, *xbot;
SNP *cupt;
vzero (top, numeg * numeg);
vzero (bot, numeg * numeg);
ZALLOC (rawcol, nrows, int);
ZALLOC (pop0, numeg, int);
ZALLOC (pop1, numeg, int);
ZALLOC (popall, numeg, int);
for (col = 0; col < ncols; ++col) {
ivzero (popall, numeg);
ivzero (pop0, numeg);
ivzero (pop1, numeg);
cupt = xsnplist[col];
getrawcol (rawcol, cupt, xindex, nrows);
for (i = 0; i < nrows; i++) {
k = xtypes[i];
g = rawcol[i];
if (g < 0)
continue;
pop1[k] += g;
pop0[k] += 2 - g;
popall[k] += 2; // code needs chamging for X
}
for (k = 0; k < numeg; k++) {
ya = pop0[k];
yb = pop1[k];
top[k * numeg + k] += 2 * ya * yb;
y = ya + yb;
bot[k * numeg + k] += y * (y - 1.0);
for (j = k + 1; j < numeg; j++) {
ya = pop0[j];
yb = pop1[k];
y = ya + yb;
top[k * numeg + j] += ya * yb;
ya = pop1[j];
yb = pop0[k];
top[j * numeg + k] = top[k * numeg + j] += ya * yb;
ya = popall[k];
yb = popall[j];
bot[k * numeg + j] += ya * yb;
top[j * numeg + k] = top[k * numeg + j];
bot[j * numeg + k] = bot[k * numeg + j];
}
}
}
ZALLOC (xtop, numeg * numeg, double);
ZALLOC (xbot, numeg * numeg, double);
copyarr (bot, xbot, numeg * numeg);
y = bal1 (xbot, numeg * numeg);
vst (xtop, top, 1.0 / y, numeg * numeg);
free (xtop);
free (xbot);
free (rawcol);
free (pop0);
free (pop1);
free (popall);
}
void
setblocks (int *block, int *bsize, int *nblock, SNP ** snpm, int numsnps,
double blocklen)
// block, bsize are first element and block length
// must have been allocated if not NULL
{
int n = 0, i;
int chrom, xsize, lchrom, olds;
double fpos, dis, gpos;
SNP *cupt;
lchrom = -1;
xsize = 0;
fpos = -1.0e20;
for (i = 0; i < numsnps; i++) {
cupt = snpm[i];
cupt->tagnumber = -1;
if (cupt->ignore)
continue;
if (cupt->isfake)
continue;
chrom = cupt->chrom;
gpos = cupt->genpos;
dis = gpos - fpos;
if ((chrom != lchrom) || (dis >= blocklen)) {
if (xsize > 0) {
if (block != NULL)
block[n] = olds;
if (bsize != NULL)
bsize[n] = xsize;
++n;
}
lchrom = chrom;
fpos = gpos;
olds = i;
xsize = 0;
}
cupt->tagnumber = n;
++xsize;
}
if (xsize > 0) {
if (block != NULL)
block[n] = olds;
if (bsize != NULL)
bsize[n] = xsize;
++n;
}
*nblock = n;
return;
}
int
numblocks (SNP ** snpm, int numsnps, double blocklen)
{
int n;
setblocks (NULL, NULL, &n, snpm, numsnps, blocklen);
return n;
}
void
corrwjack (double *xrho, double *xsig, double *z1, double *z2, int ncols,
int *bcols, int nblocks)
{
double *gdot, *dot, *wdot;
double **bdot;
double *djack, *wjack;
double rho, jest, jsig;
double y1, y2;
int bnum, i, k;
ZALLOC (djack, nblocks, double);
ZALLOC (wjack, nblocks, double);
ZALLOC (gdot, 6, double);
ZALLOC (wdot, 6, double);
bdot = initarray_2Ddouble (nblocks, 6, 0.0);
for (i = 0; i < ncols; i++) {
bnum = bcols[i];
if (bnum < 0)
continue;
++wjack[bnum];
dot = bdot[bnum];
y1 = z1[i];
y2 = z2[i];
dot[0] += y1 * y1;
dot[1] += y2 * y2;
dot[2] += y1 * y2;
dot[3] += y1;
dot[4] += y2;
dot[5] += 1.0;
}
for (k = 0; k < nblocks; k++) {
dot = bdot[k];
vvp (gdot, gdot, dot, 6);
}
rho = crho (gdot);
// printmatw(gdot, 1, 6, 6) ;
for (k = 0; k < nblocks; k++) {
dot = bdot[k];
vvm (wdot, gdot, dot, 6);
djack[k] = crho (wdot);
}
wjackest (&jest, &jsig, rho, djack, wjack, nblocks);
*xrho = jest;
*xsig = jsig;
free (djack);
free (wjack);
free (gdot);
free (wdot);
free2D (&bdot, nblocks);
}
double
crho (double *stats)
{
/* correlation from 6 sufficient statistics */
double m1, m2, top, bot, b1, b2, rr;
double s1, s2, s11, s22, s12, yn;
static int ncall = 0;
++ncall;
s11 = stats[0];
s22 = stats[1];
s12 = stats[2];
s1 = stats[3];
s2 = stats[4];
yn = stats[5];
m1 = s1 / yn;
m2 = s2 / yn;
top = s12 - yn * m1 * m2;
b1 = s11 - yn * m1 * m1;
b2 = s22 - yn * m2 * m2;
if (ncall < -1) {
printf ("%9.3f\n", m1);
printf ("%9.3f\n", m2);
printf ("%9.3f\n", top);
printf ("%9.3f\n", b1);
printf ("%9.3f\n", b2);
}
rr = top / sqrt (b1 * b2);
return rr;
}
void
setbcols (SNP ** xsnplist, int ncols, int *bcols)
{
int col, bnum;
SNP *cupt;
ivclear (bcols, -1, ncols);
for (col = 0; col < ncols; ++col) {
cupt = xsnplist[col];
bnum = cupt->tagnumber;
bcols[col] = bnum;
}
}
double
doadmlin (double *jest, double *jsig, double *zlin, double *var,
SNP ** xsnplist, int *xindex, int *xtypes, int nrows, int ncols,
int numeg, int nblocks, double scale, Indiv ** indm)
{
int t1, t2, kret;
int a, b, c;
int ng3, ng2;
int c1[2], c2[2], *cc;
int *rawcol, *popall, *pop0, *pop1;
int k, g, i, col, j, d;
double ya, yb, y, mean;
SNP *cupt;
double *top, *bot, *djack, *wjack, *gtop, *gbot, *wbot, *wtop;
double **btop, **bbot, wt;
double *w1, *w2, *w3;
double ytop, ybot;
double y1, y2, yscal;
double xest, xsig, ynominal;
int bnum;
double *f3, *f3sig;
double *estmat, *zl, *rhs, errest;
double *vmean, **vjmean;
ng2 = numeg * numeg;
ng3 = numeg * numeg * numeg;
ZALLOC (f3, ng3, double);
ZALLOC (f3sig, ng3, double);
ZALLOC (w1, ng3 + 2, double);
ZALLOC (w2, ng3 + 2, double);
ZALLOC (estmat, ng3, double);
ZALLOC (w3, ng3, double);
ZALLOC (gtop, ng3, double);
ZALLOC (gbot, ng3, double);
ZALLOC (wtop, ng3, double);
ZALLOC (wbot, ng3, double);
ZALLOC (djack, nblocks, double);
ZALLOC (wjack, nblocks, double);
btop = initarray_2Ddouble (nblocks, ng3, 0.0);
bbot = initarray_2Ddouble (nblocks, ng3, 0.0);
d = numeg - 1;
vjmean = initarray_2Ddouble (nblocks, numeg, 0.0);
ZALLOC (vmean, numeg, double);
zl = w1;
rhs = w2; // overloading
for (col = 0; col < ncols; ++col) {
cupt = xsnplist[col];
if (cupt->ignore)
continue;
wt = cupt->weight;
if (wt <= 0.0)
continue;
bnum = cupt->tagnumber;
if (bnum < 0)
continue;
++wjack[bnum];
top = btop[bnum];
bot = bbot[bnum];
kret = f3yyx (estmat, cupt, xindex, xtypes, nrows, numeg, indm);
if (kret < 0)
continue;
vst (estmat, estmat, wt * scale, ng3);
vvp (top, top, estmat, ng3);
vsp (bot, bot, 1.0, ng3);
}
for (k = 0; k < nblocks; k++) {
top = btop[k];
bot = bbot[k];
vvp (gtop, gtop, top, ng3);
vvp (gbot, gbot, bot, ng3);
}
vsp (w2, gbot, 1.0e-10, ng3);
vvd (f3, gtop, w2, ng3);
vzero (zl, numeg);
estmix (zl + 1, f3, numeg);
copyarr (zl + 1, vmean, d);
ynominal = y = estmix (zlin, f3, numeg);
if (verbose) {
for (i = 0; i < numeg; ++i) {
printf ("f3: base number %d:\n", i);
printmatw (f3 + i * numeg * numeg, numeg, numeg, numeg);
}
printf ("nominal error: %12.6f\n", y);
}
ytop = ybot = errest = 0.0;
vvd (wtop, gtop, gbot, ng3); // delete-block estimate
for (k = 0; k < nblocks; k++) {
top = btop[k];
bot = bbot[k];
vvm (wtop, gtop, top, ng3);
vvm (wbot, gbot, bot, ng3);
vsp (wbot, wbot, 1.0e-10, ng3);
vvd (wtop, wtop, wbot, ng3); // delete-block estimate
vzero (zl, numeg);
djack[k] = estmix (zl + 1, wtop, numeg);
copyarr (zl + 1, vjmean[k], d);
/// printf("yyy: %4d %9.3f %12.6f\n", k, wjack[k], djack[k]) ;
mulmat (rhs, top, zl, numeg, numeg, 1);
y = vdot (zl, rhs, numeg);
ytop += y;
ybot += bot[0];
if (verbose)
printf ("www: %4d %9.3f %12.6f\n", k, wjack[k], y);
}
errest = ytop / ybot;
// jackknife estimate of standard error for variance
wjackest (&xest, &xsig, ynominal, djack, wjack, nblocks);
wjackvest (vmean, var, d, zlin, vjmean, wjack, nblocks);
*jest = xest;
*jsig = xsig;
free (w1);
free (w2);
free (w3);
free (estmat);
free (gbot);
free (wtop);
free (wbot);
free (djack);
free (wjack);
free (f3);
free (f3sig);
free (vmean);
free2D (&btop, nblocks);
free2D (&bbot, nblocks);
free2D (&vjmean, nblocks);
return errest;
}
void
dof3 (double *f3, double *f3sig, SNP ** xsnplist, int *xindex, int *xtypes,
int nrows, int ncols, int numeg, int nblocks, double scale, int mode)
{
int t1, t2;
int a, b, c;
int ng3;
int c1[2], c2[2], *cc;
int *rawcol, *popall, *pop0, *pop1;
int k, g, i, col, j;
double ya, yb, y, jest, jsig, mean;
SNP *cupt;
double *top, *bot, *djack, *wjack, *gtop, *gbot, *wbot, *wtop;
double **btop, **bbot, wt;
double *w1, *w2, *w3;
double ytop, ybot;
double y1, y2, yscal;
int bnum;
double *estmat;
ng3 = numeg * numeg * numeg;
ZALLOC (w1, ng3, double);
ZALLOC (w2, ng3, double);
ZALLOC (estmat, ng3, double);
ZALLOC (w3, ng3, double);
ZALLOC (gtop, ng3, double);
ZALLOC (gbot, ng3, double);
ZALLOC (wtop, ng3, double);
ZALLOC (wbot, ng3, double);
ZALLOC (djack, nblocks, double);
ZALLOC (wjack, nblocks, double);
btop = initarray_2Ddouble (nblocks, ng3, 0.0);
bbot = initarray_2Ddouble (nblocks, ng3, 0.0);
for (col = 0; col < ncols; ++col) {
cupt = xsnplist[col];
if (cupt->ignore)
continue;
wt = cupt->weight;
if (wt <= 0.0)
continue;
bnum = cupt->tagnumber;
if (bnum < 0)
continue;
++wjack[bnum];
top = btop[bnum];
bot = bbot[bnum];
f3yy (estmat, cupt, xindex, xtypes, nrows, numeg);
if (mode != 2) {
vst (estmat, estmat, wt, ng3);
vvp (top, top, estmat, ng3);
vsp (bot, bot, 1.0, ng3);
}
else {
vvp (top, top, estmat, ng3);
vsp (bot, bot, 1.0 / wt, ng3);
}
}
for (k = 0; k < nblocks; k++) {
top = btop[k];
bot = bbot[k];
vvp (gtop, gtop, top, ng3);
vvp (gbot, gbot, bot, ng3);
}
vsp (w2, gbot, 1.0e-10, ng3);
vvd (f3, gtop, w2, ng3);
for (k = 0; k < nblocks; k++) {
top = btop[k];
bot = bbot[k];
vvm (wtop, gtop, top, ng3);
vvm (wbot, gbot, bot, ng3);
vsp (wbot, wbot, 1.0e-10, ng3);
vvd (top, wtop, wbot, ng3); // delete-block estimate
}
vsp (gbot, gbot, 1.0e-10, ng3);
vvd (gtop, gtop, gbot, ng3);
for (a = 0; a < numeg; a++) {
for (b = 0; b < numeg; b++) {
for (c = 0; c < numeg; c++) {
if (a == b)
continue;
if (a == c)
continue;
if (c < b)
continue;
for (k = 0; k < nblocks; k++) {
top = btop[k];
djack[k] = dump3 (top, a, b, c, numeg);
}
mean = dump3 (gtop, a, b, c, numeg);
wjackest (&jest, &jsig, mean, djack, wjack, nblocks);
bump3 (f3sig, a, b, c, numeg, jsig);
bump3 (f3sig, a, c, b, numeg, jsig);
}
}
}
vst (f3, f3, scale, ng3);
vst (f3sig, f3sig, scale, ng3);
free (w1);
free (w2);
free (w3);
free (estmat);
free (gbot);
free (wtop);
free (wbot);
free (djack);
free (wjack);
free2D (&btop, nblocks);
free2D (&bbot, nblocks);
}
void
bump2 (double *x, int a, int b, int n, double val)
{
int k;
k = a;
k *= n;
k += b;
x[k] += val;
}
void
bump3 (double *x, int a, int b, int c, int n, double val)
{
int k;
k = a;
k *= n;
k += b;
k *= n;
k += c;
x[k] += val;
}
double
dump2 (double *x, int a, int b, int n)
{
int k;
double val;
k = a;
k *= n;
k += b;
val = x[k];
return val;
}
double
dump3 (double *x, int a, int b, int c, int n)
{
int k;
double val;
k = a;
k *= n;
k += b;
k *= n;
k += c;
val = x[k];
return val;
}
void
dof4 (double *f4, double *f4sig, SNP ** xsnplist, int *xindex, int *xtypes,
int nrows, int ncols, int numeg, int nblocks, double scale, int mode)
{
int t1, t2;
int a, b, c, d;
int ng4;
int c1[2], c2[2], *cc;
int *rawcol, *popall, *pop0, *pop1;
int k, g, i, col, j;
double ya, yb, y, jest, jsig, mean;
SNP *cupt;
double *top, *bot, *djack, *wjack, *gtop, *gbot, *wbot, *wtop;
double *xtop, *xbot;
double **btop, **bbot, wt;
double *w1, *w2, *w3;
double ytop, ybot;
double y1, y2, yscal;
int bnum;
int nloop = 0;
ng4 = numeg * numeg * numeg * numeg;
ZALLOC (w1, ng4, double);
ZALLOC (w2, ng4, double);
ZALLOC (w3, ng4, double);
ZALLOC (gtop, ng4, double);
ZALLOC (gbot, ng4, double);
ZALLOC (wtop, ng4, double);
ZALLOC (wbot, ng4, double);
ZALLOC (djack, nblocks, double);
ZALLOC (wjack, nblocks, double);
ZALLOC (xtop, nblocks, double);
ZALLOC (xbot, nblocks, double);
btop = initarray_2Ddouble (nblocks, ng4, 0.0);
bbot = initarray_2Ddouble (nblocks, ng4, 0.0);
for (col = 0; col < ncols; ++col) {
cupt = xsnplist[col];
if (cupt->ignore)
continue;
wt = cupt->weight;
if (wt <= 0.0)
continue;
loadaa (cupt, xindex, xtypes, nrows, numeg);
bnum = cupt->tagnumber;
if (bnum < 0)
continue;
if (bnum >= nblocks)
fatalx ("logic bug\n");
++wjack[bnum];
top = btop[bnum];
bot = bbot[bnum];
for (a = 0; a < numeg; a++) {
for (b = 0; b < numeg; b++) {
for (c = 0; c < numeg; c++) {
for (d = 0; d < numeg; d++) {
if (a == b)
continue;
if (a == c)
continue;
if (a == d)
continue;
if (b == c)
continue;
if (b == d)
continue;
if (c == d)
continue;
if (b < a)
continue;
if (c < a)
continue;
if (d < a)
continue;
if (d < c)
continue;
// f4y(&ytop, cupt, xindex, xtypes, nrows, a, b, c, d) ;
if (aafreq[a] < -1.0)
continue;
if (aafreq[b] < -1.0)
continue;
if (aafreq[c] < -1.0)
continue;
if (aafreq[d] < -1.0)
continue;
ytop = (aafreq[a] - aafreq[b]) * (aafreq[c] - aafreq[d]);
++nloop;
// if (nloop<100) printf("zz1 %d %d %d %d %9.3f\n", a, b, c, d, ytop) ;
if (isnan (ytop))
fatalx ("zznan\n");
if (mode != 2) {
bump4x (top, a, b, c, d, numeg, wt * ytop);
bump4x (top, b, a, c, d, numeg, -wt * ytop);
bump4x (bot, a, b, c, d, numeg, 1.0);
bump4x (bot, b, a, c, d, numeg, 1.0);
}
else {
bump4x (top, a, b, c, d, numeg, ytop);
bump4x (top, b, a, c, d, numeg, -ytop);
bump4x (bot, a, b, c, d, numeg, 1.0 / wt);
bump4x (bot, b, a, c, d, numeg, 1.0 / wt);
}
}
}
}
}
}
for (a = 0; a < numeg; a++) {
for (b = 0; b < numeg; b++) {
for (c = 0; c < numeg; c++) {
for (d = 0; d < numeg; d++) {
if (a == b)
continue;
if (a == c)
continue;
if (a == d)
continue;
if (b == c)
continue;
if (b == d)
continue;
if (c == d)
continue;
if (b < a)
continue;
if (c < a)
continue;
if (d < a)
continue;
if (d < c)
continue;
for (k = 0; k < nblocks; k++) {
top = btop[k];
bot = bbot[k];
xtop[k] = dump4 (top, a, b, c, d, numeg);
xbot[k] = dump4 (bot, a, b, c, d, numeg);
}
estjackq (&jest, &jsig, xtop, xbot, wjack, nblocks);
set4x (f4sig, a, b, c, d, numeg, jsig);
set4x (f4sig, b, a, c, d, numeg, jsig);
set4x (f4, a, b, c, d, numeg, jest);
set4x (f4, b, a, c, d, numeg, jest);
}
}
}
}
vst (f4, f4, scale, ng4);
vst (f4sig, f4sig, scale, ng4);
free (w1);
free (w2);
free (w3);
free (gbot);
free (wtop);
free (wbot);
free (djack);
free (wjack);
free (xtop);
free (xbot);
free2D (&btop, nblocks);
free2D (&bbot, nblocks);
}
void
bump4x (double *x, int a, int b, int c, int d, int n, double val)
{
bump4 (x, a, b, c, d, n, val);
bump4 (x, b, a, d, c, n, val);
bump4 (x, c, d, a, b, n, val);
bump4 (x, d, c, b, a, n, val);
}
void
bump4 (double *x, int a, int b, int c, int d, int n, double val)
{
int k;
k = a;
k *= n;
k += b;
k *= n;
k += c;
k *= n;
k += d;
x[k] += val;
}
void
set4x (double *x, int a, int b, int c, int d, int n, double val)
{
set4 (x, a, b, c, d, n, val);
set4 (x, b, a, d, c, n, val);
set4 (x, c, d, a, b, n, val);
set4 (x, d, c, b, a, n, val);
}
void
set4 (double *x, int a, int b, int c, int d, int n, double val)
{
int k;
k = a;
k *= n;
k += b;
k *= n;
k += c;
k *= n;
k += d;
x[k] = val;
}
double
dump4 (double *x, int a, int b, int c, int d, int n)
{
int k;
double val;
k = a;
k *= n;
k += b;
k *= n;
k += c;
k *= n;
k += d;
val = x[k];
return val;
}
void
map4x (double *aa, double *bb, int n2, int *indx)
// map 4d array (n1 x n1 x n1 x n1 -> b n2 x n2 x n2 x n2
// intended for covariance matrix
{
int u, v, a, b, c, d, s, t;
int x;
double y1, y2;
int nh2;
int debug;
nh2 = n2 * (n2 - 1);
nh2 /= 2;
vzero (bb, n2 * n2 * n2 * n2);
for (u = 0; u < nh2; ++u) {
for (v = u; v < nh2; ++v) {
x = indx[u];
a = x / n2;
b = x % n2;
x = indx[v];
c = x / n2;
d = x % n2;
y1 = aa[u * nh2 + v];
set4x (bb, a, b, c, d, n2, y1);
set4x (bb, b, a, c, d, n2, y1);
}
}
}
double
dofstnumx (double *fst, double *fstest, double *fstsig, SNP ** xsnplist,
int *xindex, int *xtypes, int nrows, int ncols, int numeg,
int nblocks, Indiv ** indivmarkers, int fstmode)
// fstmode is classic mode (smartpca)
// fstmode 2 is fstdmode
{
int t1, t2;
int a, b;
int c1[2], c2[2], *cc;
int *rawcol, *popall, *pop0, *pop1;
int t, k, g, i, col, j;
double ya, yb, y, jest, jsig, mean;
SNP *cupt;
double *top, *bot, *djack, *wjack, *gtop, *gbot, *wbot, *wtop;
double **btop, **bbot, wt;
double *w1, *w2, *w3;
double ytop, ybot;
double y1, y2, yscal;
int bnum;
int nloop = 0, fstdnum = 0;
double *ztop, *zbot, qtop, qbot;
char **eglist;
indm = indivmarkers;
if ((fstdetails != NULL) && (indm == NULL))
fatalx ("bug in dofstnumx\n");
ZALLOC (eglist, numeg, char *);
for (k = 0; k < nrows; ++k) {
if (indm == NULL)
break;
j = xtypes[k];
if (j < 0)
continue;
if (j >= numeg)
continue;
t = xindex[k];
eglist[j] = indm[t]->egroup;
}
ZALLOC (w1, numeg * numeg, double);
ZALLOC (w2, numeg * numeg, double);
ZALLOC (w3, numeg * numeg, double);
ZALLOC (gtop, numeg * numeg, double);
ZALLOC (gbot, numeg * numeg, double);
ZALLOC (wtop, numeg * numeg, double);
ZALLOC (wbot, numeg * numeg, double);
ZALLOC (djack, nblocks, double);
ZALLOC (wjack, nblocks, double);
ZALLOC (ztop, numeg * numeg, double);
ZALLOC (zbot, numeg * numeg, double);
btop = initarray_2Ddouble (nblocks, numeg * numeg, 0.0);
bbot = initarray_2Ddouble (nblocks, numeg * numeg, 0.0);
vzero (fst, numeg * numeg);
vzero (fstest, numeg * numeg);
vzero (fstsig, numeg * numeg);
for (col = 0; col < ncols; ++col) {
cupt = xsnplist[col];
if (cupt->ignore)
continue;
wt = cupt->weight;
if (wt <= 0.0)
continue;
bnum = cupt->tagnumber;
if (bnum < 0)
continue;
++wjack[bnum];
top = btop[bnum];
bot = bbot[bnum];
fstcolyy (ztop, zbot, cupt, xindex, xtypes, nrows, numeg);
for (a = 0; a < numeg; a++) {
for (b = a + 1; b < numeg; b++) {
k = a * numeg + b;
ytop = ztop[k];
ybot = zbot[k];
if (fstdetails != NULL) {
if (fstdnum == 0) {
fprintf (fstdetails, "%15s ", "## pop 1");
fprintf (fstdetails, "%15s ", "pop 2");
fprintf (fstdetails, "%15s ", "snpname");
fprintf (fstdetails, "%12s ", "N");
fprintf (fstdetails, "%12s ", "D");
fprintf (fstdetails, "\n");
}
fprintf (fstdetails, "%15s ", eglist[a]);
fprintf (fstdetails, "%15s ", eglist[b]);
fprintf (fstdetails, "%15s ", cupt->ID);
fprintf (fstdetails, "%12.6f ", ytop);
fprintf (fstdetails, "%12.6f ", ybot);
fprintf (fstdetails, "\n");
++fstdnum;
}
if (ybot < 0.0)
continue;
if (fstmode == NO) {
top[k] += wt * ytop;
bot[k] += 1.0;
}
if (fstmode == YES) {
top[k] += ytop;
bot[k] += ybot;
}
if (fstmode == 2) {
top[k] += ytop;
bot[k] += 1.0 / wt;
}
w1[k] += ytop;
w2[k] += ybot;
// classic fst estimate
}
}
}
// symmetrize
for (a = 0; a < numeg; a++) {
for (b = a + 1; b < numeg; b++) {
top[b * numeg + a] = top[a * numeg + b];
bot[b * numeg + a] = bot[a * numeg + b];
w1[b * numeg + a] = w1[a * numeg + b];
w2[b * numeg + a] = w2[a * numeg + b];
}
}
// printf("zzz ") ; printmat(wjack, 1, nblocks) ;
vsp (w2, w2, 1.0e-10, numeg * numeg);
vvd (fst, w1, w2, numeg * numeg);
for (k = 0; k < nblocks; k++) {
top = btop[k];
bot = bbot[k];
vvp (gtop, gtop, top, numeg * numeg);
vvp (gbot, gbot, bot, numeg * numeg);
}
for (k = 0; k < nblocks; k++) {
top = btop[k];
bot = bbot[k];
vvm (wtop, gtop, top, numeg * numeg);
vvm (wbot, gbot, bot, numeg * numeg);
vsp (wbot, wbot, 1.0e-10, numeg * numeg);
vvd (top, wtop, wbot, numeg * numeg); // delete-block estimate
}
vsp (gbot, gbot, 1.0e-10, numeg * numeg);
vvd (gtop, gtop, gbot, numeg * numeg);
for (i = 0; i < numeg; i++) {
for (j = i + 1; j < numeg; j++) {
for (k = 0; k < nblocks; k++) {
top = btop[k];
djack[k] = top[i * numeg + j];
}
++nloop;
mean = gtop[i * numeg + j];
wjackest (&jest, &jsig, mean, djack, wjack, nblocks);
fstest[i * numeg + j] = fstest[j * numeg + i] = jest;
fstsig[i * numeg + j] = fstsig[j * numeg + i] = jsig;
if (nloop == -1) {
printf ("ddd\n");
printf ("mean: %9.3f\n", mean);
printmat (djack, 1, nblocks);
printmat (wjack, 1, nblocks);
printf ("%9.3f %9.3f\n", jest, jsig);
}
}
}
/**
printf("fst:\n") ;
printmat(fst, numeg, numeg) ;
printnl() ;
printmat(fstest, numeg, numeg) ;
printnl() ;
printmat(fstsig, numeg, numeg) ;
printnl() ;
*/
yscal = 1.0;
if (fstmode != YES) {
copyarr (fstsig, w3, numeg * numeg);
vsp (w3, w3, 1.0e-10, numeg * numeg);
vvd (w1, fst, w3, numeg * numeg);
vvd (w2, fstest, w3, numeg * numeg);
// now do regression w1 = yscal * w2
y1 = vdot (w1, w2, numeg * numeg);
y2 = vdot (w2, w2, numeg * numeg);
yscal = y1 / y2;
vst (fstest, fstest, yscal, numeg * numeg);
vst (fstsig, fstsig, yscal, numeg * numeg);
}
free (eglist);
free (w1);
free (w2);
free (w3);
free (gbot);
free (wtop);
free (wbot);
free (ztop);
free (zbot);
free (djack);
free (wjack);
free2D (&btop, nblocks);
free2D (&bbot, nblocks);
return yscal;
}
double
dofstnum (double *fst, double *fstest, double *fstsig, SNP ** xsnplist,
int *xindex, int *xtypes, int nrows, int ncols, int numeg,
int nblocks)
{
return dofstnumx (fst, fstest, fstsig, xsnplist, xindex, xtypes, nrows, ncols,
numeg, nblocks, NULL, NO);
}
void
setmgpos (SNP ** snpm, int numsnps, double *maxgdis)
// find max genetic distance
{
double minpos, maxdis;
int chrom, lchrom, i;
SNP *cupt;
minpos = 99999.0;
lchrom = -1;
maxdis = -9999;
for (i = 0; i < numsnps; i++) {
cupt = snpm[i];
chrom = cupt->chrom;
if (chrom != lchrom) {
lchrom = chrom;
minpos = cupt->genpos;
}
maxdis = MAX (maxdis, cupt->genpos - minpos);
}
*maxgdis = maxdis;
}
void
setgfromp (SNP ** snpm, int numsnps)
{
int i;
SNP *cupt;
for (i = 0; i < numsnps; i++) {
cupt = snpm[i];
cupt->genpos = (cupt->physpos) / 1.0e8;
}
}
void
setjquart (int pjack, int jackw, double qq)
{
jackweight = jackw;
quartile = qq;
pubjack = pjack;
}
void
wjackest (double *est, double *sig, double mean, double *jmean, double *jwt,
int g)
// test for jwt 0
{
double *jjmean, *jjwt;
int i, n;
ZALLOC (jjmean, g, double);
ZALLOC (jjwt, g, double);
n = 0;
for (i = 0; i < g; ++i) {
if (jwt[i] < 1.0e-6)
continue;
jjmean[n] = jmean[i];
jjwt[n] = jwt[i];
++n;
}
wjackestx (est, sig, mean, jjmean, jjwt, n);
free (jjmean);
free (jjwt);
}
void
oldwjackest (double *est, double *sig, double mean, double *jmean,
double *jwt, int g)
// test for jwt 0 funky stuff OOD
{
double *jjmean, *jjwt;
int *ord;
int i, n, m;
double y, mmean;
ZALLOC (jjmean, g, double);
ZALLOC (jjwt, g, double);
n = 0;
for (i = 0; i < g; ++i) {
if (jwt[i] < 1.0e-6)
continue;
jjmean[n] = jmean[i];
jjwt[n] = jwt[i];
++n;
}
m = 0;
mmean = mean;
if (jackweight == NO)
vclear (jjwt, 1.0, n);
if (quartile > 0.0) {
ZALLOC (ord, n, int);
sortit (jjmean, ord, n);
dpermute (jjwt, ord, n);
free (ord);
y = quartile * (double) n;
m = nnint (y);
mmean = vdot (jjmean + m, jjwt + m, n - m) / asum (jjwt + m, n - m);
}
if (pubjack) {
printf ("pubjack\n");
printmatwl (jjmean, 1, n, 1);
}
wjackestx (est, sig, mmean, jjmean + m, jjwt + m, n - m);
free (jjmean);
free (jjwt);
}
static void
wjackestx (double *est, double *sig, double mean, double *jmean, double *jwt,
int g)
// weighted jackknife see wjack.tex
// mean is natural estimate. jmean[k] mean with block k removed. jwt is weight for block (sample size)
{
double *tdiff, *hh, *xtau, *w1, *w2;
double jackest, yn, yvar;
int k;
if (g <= 1)
fatalx ("(wjackest) number of blocks <= 1\n");
ZALLOC (tdiff, g, double);
ZALLOC (hh, g, double);
ZALLOC (xtau, g, double);
ZALLOC (w1, g, double);
ZALLOC (w2, g, double);
yn = asum (jwt, g);
vsp (tdiff, jmean, -mean, g);
vst (tdiff, tdiff, -1.0, g);
jackest = asum (tdiff, g) + vdot (jwt, jmean, g) / yn;
// this is equation 2
vclear (hh, yn, g);
vvd (hh, hh, jwt, g);
/**
for (k=0; k<g; ++k) {
if (jwt[k] > 0.0) hh[k] /= jwt[k] ;
else hh[k] *= 1.0e20 ;
}
*/
// jwt should be positive
vst (xtau, hh, mean, g);
vsp (w1, hh, -1.0, g);
vvt (w2, w1, jmean, g);
vvm (xtau, xtau, w2, g);
vsp (xtau, xtau, -jackest, g);
vvt (xtau, xtau, xtau, g);
vvd (xtau, xtau, w1, g);
yvar = asum (xtau, g) / (double) g;
*est = jackest;
*sig = sqrt (yvar);
free (tdiff);
free (hh);
free (xtau);
free (w1);
free (w2);
}
void
ndfst5 (double *zzest, double *zzsig, double **zn, double **zd, int ncols,
int *bcols, int nblocks)
{
#define NPAR 5
double *djack, *wjack;
double qest, jest, jsig;
double y1, y2;
int bnum, i, k;
int a, b, c;
double *gn, *gd, **xn, **xd, *xx, *qqest, *test, *tn, *td, **xqest;
ZALLOC (gn, 4 * 4, double);
ZALLOC (gd, 4 * 4, double);
ZALLOC (tn, 4 * 4, double);
ZALLOC (td, 4 * 4, double);
ZALLOC (qqest, NPAR, double);
ZALLOC (djack, nblocks, double);
ZALLOC (wjack, nblocks, double);
xn = initarray_2Ddouble (nblocks, 4 * 4, 0.0);
xd = initarray_2Ddouble (nblocks, 4 * 4, 0.0);
xqest = initarray_2Ddouble (nblocks, NPAR, 0.0);
for (i = 0; i < ncols; i++) {
bnum = bcols[i];
if (bnum < 0)
continue;
if (bnum >= nblocks)
fatalx ("bad bug\n");
++wjack[bnum];
for (a = 0; a < 4; a++) {
for (b = a + 1; b < 4; b++) {
c = 4 * a + b;
xn[bnum][c] += zn[i][c];
xd[bnum][c] += zd[i][c];
}
}
}
for (k = 0; k < nblocks; k++) {
xx = xn[k];
vvp (gn, gn, xx, 4 * 4);
xx = xd[k];
vvp (gd, gd, xx, 4 * 4);
}
verbose = YES;
regestit (qqest, gn, gd);
printf ("qqest: ");
printmatw (qqest, 1, 5, 5);
verbose = NO;
for (k = 0; k < nblocks; k++) {
xx = xn[k];
vvm (tn, gn, xx, 4 * 4);
xx = xd[k];
vvm (td, gd, xx, 4 * 4);
regestit (xqest[k], tn, td);
}
for (a = 0; a < NPAR; a++) {
for (k = 0; k < nblocks; ++k) {
djack[k] = xqest[k][a];
}
wjackest (&jest, &jsig, qqest[a], djack, wjack, nblocks);
zzest[a] = jest;
zzsig[a] = jsig;
}
free2D (&xqest, nblocks);
free2D (&xn, nblocks);
free2D (&xd, nblocks);
free (djack);
free (wjack);
free (gn);
free (gd);
free (tn);
free (td);
free (qqest);
}
void
regestit (double *ans, double *xn, double *xd)
{
int a, b, c, k;
double *co, *rr;
double f;
ZALLOC (co, 6 * 5, double);
ZALLOC (rr, 6, double);
/**
printf("zzreg\n") ;
printmat(xn, 4, 4) ;
printnl() ;
printmat(xd, 4, 4) ;
printnl() ;
*/
verbose = NO;
k = 0;
a = 0;
b = 1;
c = 4 * a + b;
f = xn[c] / xd[c];
co[k * 5 + 0] = co[k * 5 + 1] = 1;
rr[k] = f;
k = 1;
a = 2;
b = 3;
c = 4 * a + b;
f = xn[c] / xd[c];
co[k * 5 + 3] = co[k * 5 + 4] = 1;
rr[k] = f;
k = 2;
a = 0;
b = 2;
c = 4 * a + b;
f = xn[c] / xd[c];
co[k * 5 + 0] = co[k * 5 + 2] = co[k * 5 + 3] = 1;
rr[k] = f;
k = 3;
a = 0;
b = 3;
c = 4 * a + b;
f = xn[c] / xd[c];
co[k * 5 + 0] = co[k * 5 + 2] = co[k * 5 + 4] = 1;
rr[k] = f;
k = 4;
a = 1;
b = 2;
c = 4 * a + b;
f = xn[c] / xd[c];
co[k * 5 + 1] = co[k * 5 + 2] = co[k * 5 + 3] = 1;
rr[k] = f;
k = 5;
a = 1;
b = 3;
c = 4 * a + b;
f = xn[c] / xd[c];
co[k * 5 + 1] = co[k * 5 + 2] = co[k * 5 + 4] = 1;
rr[k] = f;
regressit (ans, co, rr, 6, 5);
free (co);
free (rr);
}
void
setwt (SNP ** snpmarkers, int numsnps, Indiv ** indivmarkers, int nrows,
int *xindex, int *xtypes, char *outpop, char **eglist, int numeg)
{
int *rawcol;
SNP *cupt;
int i, k, j, t, kk, maxeg;
int a0, a1, aa;
int **ccx, **ccc, *cc;
double wt, p;
int a, g;
t = strcmp (outpop, "NONE");
if (t == 0)
outnum = -1;
t = strcmp (outpop, "NULL");
if (t == 0)
outnum = -99;
maxeg = MAX (outnum, numeg) + 1;
ccx = initarray_2Dint (maxeg, 2, 0);
ccc = initarray_2Dint (nrows, 2, 0);
t = -1;
for (i = 0; i < numsnps; ++i) {
cupt = snpmarkers[i];
cupt->weight = 0;
if (cupt->ignore)
continue;
getrawcolx (ccc, cupt, xindex, nrows, indivmarkers);
iclear2D (&ccx, maxeg, 2, 0);
for (k = 0; k < nrows; ++k) {
a = xtypes[k];
if (a < 0)
continue;
if (a >= maxeg)
continue;
g = ccc[k][0];
if (g < 0)
continue;
cc = ccx[a];
ivvp (cc, cc, ccc[k], 2);
}
if (outnum < 0) {
a0 = a1 = 0;
for (j = 0; j < numeg; ++j) {
a0 += ccx[j][0];
a1 += ccx[j][1];
}
}
else {
a0 = ccx[outnum][0];
a1 = ccx[outnum][1];
}
aa = a0 + a1;
if (a0 == 0)
continue;
if (a1 == 0)
continue;
p = (double) a0 / (double) aa;
wt = 1.0 / (p * (1.0 - p));
if (outnum == -99)
wt = 1.0;
for (k = 0; k < numeg; ++k) {
a0 = ccx[k][0];
a1 = ccx[k][1];
aa = a0 + a1;
if ((allsnpsmode == NO) && (aa < 2)) {
wt = 0;
break;
}
if (k < numeg)
continue;
}
cupt->weight = wt;
}
for (i = 0; i < numsnps; ++i) {
cupt = snpmarkers[i];
if (cupt->weight <= 0.0)
cupt->ignore = YES;
}
free2Dint (&ccx, maxeg);
free2Dint (&ccc, nrows);
}
void
countg (int *rawcol, int **cc, int *xtypes, int n, int ntypes)
{
int g, i, c0, c1, k;
iclear2D (&cc, ntypes, 2, 0);
for (i = 0; i < n; i++) {
g = rawcol[i];
if (g < 0)
continue;
c0 = g;
c1 = 2 - g;
k = xtypes[i];
if (k < 0)
continue;
if (k > ntypes)
continue;
cc[k][0] += c0;
cc[k][1] += c1;
}
}
void
dohzgjack (double *hest, double *hsig, SNP ** xsnplist, int *xindex,
int *xtypes, int nrows, int ncols, int numeg, int *bcols,
int nblocks)
{
int t1, t2;
int c1[2], c2[2], *cc;
int *rawcol, *popall, *pop0, *pop1;
int k, g, i, col, j;
double ya, yb, y, jest, jsig, mean;
SNP *cupt;
double *top, *bot, *djack, *wjack, *gtop, *gbot, *wbot, *wtop;
double **btop, **bbot;
int bnum;
ZALLOC (gtop, numeg * numeg, double);
ZALLOC (gbot, numeg * numeg, double);
ZALLOC (wtop, numeg * numeg, double);
ZALLOC (wbot, numeg * numeg, double);
ZALLOC (djack, nblocks, double);
ZALLOC (wjack, nblocks, double);
btop = initarray_2Ddouble (nblocks, numeg * numeg, 0.0);
bbot = initarray_2Ddouble (nblocks, numeg * numeg, 0.0);
ZALLOC (rawcol, nrows, int);
ZALLOC (pop0, numeg, int);
ZALLOC (pop1, numeg, int);
ZALLOC (popall, numeg, int);
ivclear (bcols, -1, ncols);
for (col = 0; col < ncols; ++col) {
ivzero (popall, numeg);
ivzero (pop0, numeg);
ivzero (pop1, numeg);
cupt = xsnplist[col];
bnum = cupt->tagnumber;
bcols[col] = bnum;
if (bnum < 0)
continue;
++wjack[bnum];
top = btop[bnum];
bot = bbot[bnum];
getrawcol (rawcol, cupt, xindex, nrows);
for (i = 0; i < nrows; i++) {
k = xtypes[i];
if (k < 0)
continue;
if (k >= numeg)
continue;
g = rawcol[i];
if (g < 0)
continue;
pop1[k] += g;
pop0[k] += 2 - g;
popall[k] += 2; // code needs chamging for X
}
for (k = 0; k < numeg; k++) {
ya = pop0[k];
yb = pop1[k];
top[k * numeg + k] += 2 * ya * yb;
y = ya + yb;
bot[k * numeg + k] += y * (y - 1.0);
for (j = k + 1; j < numeg; j++) {
ya = pop0[j];
yb = pop1[k];
y = ya + yb;
top[k * numeg + j] += ya * yb;
ya = pop1[j];
yb = pop0[k];
top[j * numeg + k] = top[k * numeg + j] += ya * yb;
ya = popall[k];
yb = popall[j];
bot[k * numeg + j] += ya * yb;
top[j * numeg + k] = top[k * numeg + j];
bot[j * numeg + k] = bot[k * numeg + j];
}
}
}
for (k = 0; k < nblocks; k++) {
top = btop[k];
bot = bbot[k];
vvp (gtop, gtop, top, numeg * numeg);
vvp (gbot, gbot, bot, numeg * numeg);
}
/**
for (k=0; k<nblocks; k++) {
top = btop[k] ;
bot = bbot[k] ;
vvp(gtop, gtop, top, numeg*numeg) ;
vvp(gbot, gbot, bot, numeg*numeg) ;
}
*/
for (k = 0; k < nblocks; k++) {
top = btop[k];
bot = bbot[k];
vvm (wtop, gtop, top, numeg * numeg);
vvm (wbot, gbot, bot, numeg * numeg);
vsp (wbot, wbot, 1.0e-10, numeg * numeg);
vvd (top, wtop, wbot, numeg * numeg); // delete-block estimate
}
vsp (gbot, gbot, 1.0e-10, numeg * numeg);
vvd (gtop, gtop, gbot, numeg * numeg);
for (i = 0; i < numeg; i++) {
for (j = i; j < numeg; j++) {
for (k = 0; k < nblocks; k++) {
top = btop[k];
djack[k] = top[i * numeg + j];
}
mean = gtop[i * numeg + j];
wjackest (&jest, &jsig, mean, djack, wjack, nblocks);
// printf("zz %d %d %12.6f %12.6f\n", i, j, mean, jest) ;
hest[i * numeg + j] = hest[j * numeg + i] = jest;
hsig[i * numeg + j] = hsig[j * numeg + i] = jsig;
}
}
free (rawcol);
free (pop0);
free (pop1);
free (popall);
free (gtop);
free (gbot);
free (wtop);
free (wbot);
free (djack);
free (wjack);
free2D (&btop, nblocks);
free2D (&bbot, nblocks);
}
void
wjackvest (double *vest, double *var, int d, double *mean, double **jmean,
double *jwt, int g)
// test for jwt 0
{
double **jjmean, *jjwt;
int i, n;
jjmean = initarray_2Ddouble (g, d, 0.0);
ZALLOC (jjwt, g, double);
n = 0;
for (i = 0; i < g; ++i) {
if (jwt[i] < 1.0e-6)
continue;
copyarr (jmean[i], jjmean[n], d);
jjwt[n] = jwt[i];
++n;
}
wjackvestx (vest, var, d, mean, jjmean, jjwt, n);
free2D (&jjmean, g);
free (jjwt);
}
static void
wjackvestx (double *vest, double *var, int d, double *mean, double **jmean,
double *jwt, int g)
// weighted jackknife see wjack.tex
// mean is natural estimate. jmean[k] mean with block k removed. jwt is weight for block (sample size)
/**
mean is d long
jjmean is [g][d] giving jackknifed estimates after deleting each block
jwt is jackknife weight (weight 0 should be OK but is deprecated
Output vest is d long (jackknife estimate)
var is error variance
*/
{
double *xtau, *hh;
double *jackest, yn, yvar;
double *wa;
int j, k;
double y1, y2;
if (g <= 1)
fatalx ("(wjackvest) not enough blocks\n");
ZALLOC (hh, g, double);
ZALLOC (xtau, d, double);
ZALLOC (wa, d, double);
jackest = vest;
vzero (var, d * d);
vzero (jackest, d);
yn = asum (jwt, g);
for (k = 0; k < g; ++k) {
vvm (wa, mean, jmean[k], d);
vvp (jackest, jackest, wa, d);
vst (wa, jmean[k], jwt[k] / yn, d);
vvp (jackest, jackest, wa, d);
}
// this is equation 2
vclear (hh, yn, g);
for (k = 0; k < g; ++k) {
if (jwt[k] > 0.0)
hh[k] /= jwt[k];
else
hh[k] *= 1.0e20;
y1 = hh[k];
vst (xtau, mean, y1, d);
--y1;
vst (wa, jmean[k], y1, d);
vvm (xtau, xtau, wa, d);
vvm (xtau, xtau, jackest, d);
y2 = 1.0 / sqrt (y1);
vst (wa, xtau, y2, d);
addouter (var, wa, d);
}
// jwt should be positive
vst (var, var, 1.0 / (double) g, d * d);
free (hh);
free (xtau);
free (wa);
}
int
f3yyx (double *estmat, SNP * cupt,
int *xindex, int *xtypes, int nrows, int numeg, Indiv ** indmx)
{
int *c1, *c2, *c3, *cc;
int *rawcol;
int k, g, i, a, b, c, t;
int a0, a1, kret;
double ya, yb, yaa, ybb, p1, p2, p3, en, ed;
double z, zz, h1, h2, h3, yt, ax1, ax2, ht1, ht2;
double ywt;
int **ccc, *gg, **ccx;
static int ncall = 0;
indm = indmx;
loadaa (cupt, xindex, xtypes, nrows, numeg);
++ncall;
vzero (estmat, numeg * numeg * numeg);
kret = 1;
for (a = 0; a < numeg; a++) {
if (aafreq[a] < -1.0) {
if (allsnpsmode == NO) {
kret = -1;
break;
}
}
for (b = 0; b < numeg; b++) {
for (c = 0; c < numeg; c++) {
if (a == b)
continue;
if (a == c)
continue;
if (c < b)
continue;
p1 = aafreq[a];
h1 = hest[a];
ht1 = htest[a];
ax1 = aaxadd[a];
p2 = aafreq[b];
h2 = hest[b];
ht2 = htest[b];
ax2 = aaxadd[b];
p3 = aafreq[c];
h3 = hest[c];
if ((p1 < -1) || (p2 < -1) || (p3 < -1)) {
if (allsnpsmode == NO) {
kret = -1;
}
if (allsnpsmode == YES) {
bump3 (estmat, a, b, c, numeg, -300);
bump3 (estmat, a, c, b, numeg, -300);
continue;
}
}
if (kret < 0)
break;
en = (p1 - p2) * (p1 - p3);
en += ax1;
en -= ht1;
if (b == c) {
en += ax2;
en -= ht2;
}
bump3 (estmat, a, b, c, numeg, en);
if (b != c)
bump3 (estmat, a, c, b, numeg, en);
t = a * numeg * numeg + b * numeg + c;
if ((t == 18) && (ncall <= -1)) {
printf ("%9.3f ", p1);
printf ("%9.3f ", p2);
printf ("%9.3f ", p3);
printf ("%9.3f ", h1);
printf ("%9.3f ", ht1);
printf ("%9.3f ", h2);
printf ("%9.3f ", ht2);
printnl ();
}
}
}
}
if (ncall < -1) {
printf ("zz1 %d\n", kret);
printmat (estmat, numeg * numeg, numeg);
}
return kret;
}
void
f3yy (double *estmat, SNP * cupt,
int *xindex, int *xtypes, int nrows, int numeg)
{
int *c1, *c2, *c3, *cc;
int *rawcol;
int k, g, i, a, b, c;
double ya, yb, yaa, ybb, p1, p2, p3, en, ed;
double z, zz, h1, h2, yt;
double ywt;
int **ccc, *gg, **ccx;
static int ncall = 0;
++ncall;
ccc = initarray_2Dint (nrows, 2, 0);
ccx = initarray_2Dint (numeg, 2, 0);
vzero (estmat, numeg * numeg * numeg);
ZALLOC (rawcol, nrows, int);
getrawcol (rawcol, cupt, xindex, nrows);
for (a = 0; a < nrows; a++) {
g = rawcol[a];
ccc[a][0] = g;
ccc[a][1] = 2 - g;
}
free (rawcol);
for (k = 0; k < nrows; ++k) {
a = xtypes[k];
if (a < 0)
continue;
if (a >= numeg)
continue;
g = ccc[k][0];
if (g < 0)
continue;
cc = ccx[a];
ivvp (cc, cc, ccc[k], 2);
}
for (a = 0; a < numeg; a++) {
for (b = 0; b < numeg; b++) {
for (c = 0; c < numeg; c++) {
if (a == b)
continue;
if (a == c)
continue;
if (c < b)
continue;
c1 = ccx[a];
c2 = ccx[b];
c3 = ccx[c];
ya = (double) c1[0];
yb = (double) c1[1];
z = ya + yb;
yt = ya + yb;
p1 = ya / yt;
h1 = ya * yb / (yt * (yt - 1.0));
yaa = (double) c2[0];
ybb = (double) c2[1];
yt = yaa + ybb;
p2 = yaa / yt;
h2 = yaa * ybb / (yt * (yt - 1.0));
zz = yaa + ybb;
yaa = (double) c3[0];
ybb = (double) c3[1];
yt = yaa + ybb;
p3 = yaa / yt;
en = (p1 - p2) * (p1 - p3);
en -= h1 / z;
if (b == c)
en -= h2 / zz;
bump3 (estmat, a, b, c, numeg, en);
if (b != c)
bump3 (estmat, a, c, b, numeg, en);
}
}
}
free2Dint (&ccc, nrows);
free2Dint (&ccx, numeg);
}
double
estmix (double *z, double *f3, int n)
/**
We minimize
{f - \sum_i w_i x_i}^2 where f is a target population or individual and x_i are
mixing coefficients. We can write this as in:
{\sum_i w_i (f-x_i)}^2 - \lam (\sum_i w_i -1)
which yields equations
\sum_j X_{ij} w_j = \lam
where X are f_3 or f_2 coefficients.
We solve this by setting lambda = 1 and then normalizing the answer to sum
to 1.
*/
{
int a, b;
int d = n - 1;
double *co, *rhs, y, *ww, *w1;
ZALLOC (co, d * d, double);
ZALLOC (ww, d * d, double);
ZALLOC (rhs, d, double);
ZALLOC (w1, d, double);
vclear (rhs, 1.0, d);
for (a = 0; a < d; a++) {
for (b = a; b < d; b++) {
y = dump3 (f3, 0, a + 1, b + 1, n);
// works if a = b as dof3 fixed up
co[a * d + b] = co[b * d + a] = y;
}
}
vclear (w1, 1.0, d);
mulmat (rhs, co, w1, d, d, 1);
mulmat (ww, co, co, d, d, d);
solvit (ww, rhs, d, z);
y = asum (z, d);
if (y == 0.0)
fatalx ("z is zero!\n");
vst (z, z, 1.0 / y, d);
mulmat (rhs, co, z, d, d, 1);
y = vdot (z, rhs, d);
free (co);
free (rhs);
free (ww);
free (w1);
return y;
}
double
ff3val (double *ff3, int a, int b, int c, int n)
{
double y;
y = dump3 (ff3, 0, a, a, n);
y += dump3 (ff3, 0, b, c, n);
y -= dump3 (ff3, 0, b, a, n);
y -= dump3 (ff3, 0, c, a, n);
return y;
}
void
estjackq (double *pjest, double *pjsig, double *btop, double *bbot,
double *wjack, int nblocks)
// use untrimmed standard error even if quartile set
{
double gtop, gbot, top, bot;
double *wtop, *wbot, ytop, ybot;
double *djack;
double jest, jsig, jsig2, mean;
int k;
double *jjmean, *jjwt;
int *ord;
int i, n, m, g;
double y, mmean;
double *xtop, *xbot, *xwt, *xmean;
ZALLOC (jjmean, nblocks, double);
ZALLOC (jjwt, nblocks, double);
ZALLOC (djack, nblocks, double);
ZALLOC (wtop, nblocks, double);
ZALLOC (wbot, nblocks, double);
if (bbot == NULL)
vclear (wbot, 1.0, nblocks);
else
copyarr (bbot, wbot, nblocks);
gtop = asum (btop, nblocks);
gbot = asum (wbot, nblocks);
mean = gtop / (gbot + 1.0e-10);
for (k = 0; k < nblocks; k++) {
top = btop[k];
bot = wbot[k];
ytop = gtop - top;
ybot = gbot - bot;
ybot += 1.0e-10;
djack[k] = ytop / ybot; // delete-block estimate
}
n = 0;
for (i = 0; i < nblocks; ++i) {
if (wjack[i] < 1.0e-6)
continue;
jjmean[n] = djack[i];
jjwt[n] = wjack[i];
wtop[n] = btop[i];
wbot[n] = wbot[i];
++n;
}
m = 0;
mmean = mean;
xwt = jjwt;
xmean = jjmean;
g = n;
wjackestx (&jest, &jsig, mmean, xmean, xwt, g);
if (jackweight == NO)
vclear (jjwt, 1.0, n);
if (quartile > 0.0) {
ZALLOC (ord, n, int);
sortit (jjmean, ord, n);
if (pubjack) {
printf ("pubjack\n");
printnorm (jjmean, n); // print normalized version
}
dpermute (jjwt, ord, n);
dpermute (wtop, ord, n);
dpermute (wbot, ord, n);
free (ord);
y = quartile * (double) n;
m = nnint (y);
g = n - 2 * m;
xbot = wbot + m;
xtop = wtop + m;
xwt = jjwt + m;
gtop = asum (xtop, g);
gbot = asum (xbot, g);
mmean = gtop / (gbot + 1.0e-10);
for (k = 0; k < g; k++) {
top = xtop[k];
bot = xbot[k];
ytop = gtop - top;
ybot = gbot - bot;
ybot += 1.0e-10;
djack[k] = ytop / ybot; // delete-block estimate
}
xmean = djack;
}
wjackestx (&jest, &jsig2, mmean, xmean, xwt, g);
*pjest = jest;
*pjsig = jsig;
free (djack);
free (jjmean);
free (jjwt);
free (wtop);
free (wbot);
}
void
printnorm (double *a, int n)
{
double *w, y1, y2;
ZALLOC (w, n, double);
y1 = asum (a, n) / (double) n;
vsp (w, a, -y1, n);
y2 = asum2 (w, n) / (double) n;
y2 = sqrt (y2 + 1.0e-20);
vst (w, w, 1.0 / y2, n);
printmatw (w, 1, n, 1);
free (w);
}
// inbreed stuff
void
fstcolinb (double *estnmat, double *estdmat, SNP * cupt,
int *xindex, int *xtypes, int nrows, int numeg)
/**
NP style n, d estimation for inbreeding, Like fstcolyy
like fstcoly but a matrix of populations so data is only accessed once
*/
{
int *c1, *c2, *cc;
int *rawcol;
int k, g, i, j, a, b;
double ya, yb, yaa, ybb, p1, p2, en, ed;
double z, zz, h1, h2, yt;
double ywt;
int **ccc, *gg, **ddd;
static int ncall = 0;
double het, hetin;
++ncall;
ccc = initarray_2Dint (nrows, 2, 0);
ddd = initarray_2Dint (numeg, 3, 0);
vzero (estnmat, numeg);
vclear (estdmat, -1.0, numeg);
if (indm == NULL) {
ZALLOC (rawcol, nrows, int);
getrawcol (rawcol, cupt, xindex, nrows);
for (a = 0; a < nrows; a++) {
g = rawcol[a];
ccc[a][0] = g;
ccc[a][1] = 2 - g;
}
free (rawcol);
}
else {
getrawcolx (ccc, cupt, xindex, nrows, indm);
}
ywt = 1.0;
for (i = 0; i < nrows; i++) {
k = xtypes[i];
if (k < 0)
continue;
if (k >= numeg)
continue;
cc = ddd[k];
gg = ccc[i];
g = gg[0];
if (g < 0)
continue;
if (g > 2)
fatalx ("fstcolinb bug\n");
if (inbreed == NO)
ivvp (cc, cc, gg, 2);
else {
a = g + gg[1];
if (a == 1)
g *= 2; // X and male
++cc[g];
}
}
for (i = 0; i < numeg; i++) {
c1 = ddd[i];
if (intsum (c1, 3) < 2)
continue;
calchetinbreed (c1, &het, &hetin);
estnmat[i] = (het - hetin) * ywt;
estdmat[i] = het * ywt;
}
free2Dint (&ccc, nrows);
free2Dint (&ddd, numeg);
}
double
doinbreed (double *inb, double *inbest, double *inbsig, SNP ** xsnplist,
int *xindex, int *xtypes, int nrows, int ncols, int numeg,
int nblocks, Indiv ** indivmarkers)
{
int t1, t2;
int a, b;
int c1[2], c2[2], *cc;
int *rawcol, *popall, *pop0, *pop1;
int t, k, g, i, col, j;
double ya, yb, y, jest, jsig, mean;
SNP *cupt;
double *top, *bot, *djack, *wjack, *gtop, *gbot, *wbot, *wtop;
double **btop, **bbot, wt;
double *w1, *w2, *w3;
double ytop, ybot;
double y1, y2, yscal;
int bnum;
int nloop = 0, fstdnum = 0;
double *ztop, *zbot, qtop, qbot;
char **eglist;
indm = indivmarkers;
ZALLOC (eglist, numeg, char *);
for (k = 0; k < nrows; ++k) {
if (indm == NULL)
break;
j = xtypes[k];
if (j < 0)
continue;
if (j >= numeg)
continue;
t = xindex[k];
eglist[j] = indm[t]->egroup;
}
ZALLOC (w1, numeg, double);
ZALLOC (w2, numeg, double);
ZALLOC (w3, numeg, double);
ZALLOC (gtop, numeg, double);
ZALLOC (gbot, numeg, double);
ZALLOC (wtop, numeg, double);
ZALLOC (wbot, numeg, double);
ZALLOC (djack, nblocks, double);
ZALLOC (wjack, nblocks, double);
ZALLOC (ztop, numeg, double);
ZALLOC (zbot, numeg, double);
btop = initarray_2Ddouble (nblocks, numeg, 0.0);
bbot = initarray_2Ddouble (nblocks, numeg, 0.0);
vzero (inb, numeg);
vzero (inbest, numeg);
vzero (inbsig, numeg);
for (col = 0; col < ncols; ++col) {
cupt = xsnplist[col];
if (cupt->ignore)
continue;
wt = cupt->weight;
if (wt <= 0.0)
continue;
bnum = cupt->tagnumber;
if (bnum < 0)
continue;
++wjack[bnum];
top = btop[bnum];
bot = bbot[bnum];
fstcolinb (ztop, zbot, cupt, xindex, xtypes, nrows, numeg);
for (a = 0; a < numeg; a++) {
k = a;
ytop = ztop[k];
ybot = zbot[k];
if (ybot < 0.0)
continue;
top[k] += ytop;
bot[k] += ybot;
w1[k] += ytop;
w2[k] += ybot;
}
}
vsp (w2, w2, 1.0e-10, numeg);
vvd (inb, w1, w2, numeg);
for (k = 0; k < nblocks; k++) {
top = btop[k];
bot = bbot[k];
vvp (gtop, gtop, top, numeg);
vvp (gbot, gbot, bot, numeg);
}
for (k = 0; k < nblocks; k++) {
top = btop[k];
bot = bbot[k];
vvm (wtop, gtop, top, numeg);
vvm (wbot, gbot, bot, numeg);
vsp (wbot, wbot, 1.0e-10, numeg);
vvd (top, wtop, wbot, numeg); // delete-block estimate
}
vsp (gbot, gbot, 1.0e-10, numeg);
vvd (gtop, gtop, gbot, numeg);
printf ("zzinb\n");
printmat (inb, 1, numeg);
printnl ();
printmat (gtop, 1, numeg);
for (i = 0; i < numeg; i++) {
for (k = 0; k < nblocks; k++) {
top = btop[k];
djack[k] = top[i];
}
++nloop;
mean = gtop[i];
wjackest (&jest, &jsig, mean, djack, wjack, nblocks);
inbest[i] = jest;
inbsig[i] = jsig;
if (nloop == -1) {
printf ("inbreedest\n");
printf ("mean: %9.3f\n", mean);
printmat (djack, 1, nblocks);
printnl ();
printmat (wjack, 1, nblocks);
printf ("%9.3f %9.3f\n", jest, jsig);
}
}
free (eglist);
free (w1);
free (w2);
free (w3);
free (gbot);
free (wtop);
free (wbot);
free (ztop);
free (zbot);
free (djack);
free (wjack);
free2D (&btop, nblocks);
free2D (&bbot, nblocks);
return 1;
}
void
setinbreed (int val)
{
inbreed = val;
if (val == YES)
printf ("inbreed set\n");
}
void
calchetinbreed (int *c1, double *phet, double *phetin)
{
double s, t, a, b, h1, h2, ex, en, ed;
double x0, x1, x2, y0, y1, y2;
*phet = *phetin = -1.0;
s = intsum (c1, 3);
if (s < 1.5)
return;
x0 = c1[0];
x1 = c1[1];
x2 = c1[2];
h1 = x0 * x2 + (x0 + x2) * x1 / 2 + x1 * (x1 - 1) / 4;
h1 /= (double) (s * (s - 1));
*phet = 2 * h1;
*phetin = x1 / (double) s; //naive estimate, unbiased
}
void
calcndinbreed (int *c1, int *c2, double *pen, double *ped)
{
double s, t, a, b, h1, h2, ex, en, ed;
double x0, x1, x2, y0, y1, y2;
*pen = *ped = -1.0;
s = intsum (c1, 3);
t = intsum (c2, 3);
if (s < 1.5)
return;
if (t < 1.5)
return;
x0 = c1[0];
x1 = c1[1];
x2 = c1[2];
y0 = c2[0];
y1 = c2[1];
y2 = c2[2];
a = (x1 + 2 * x2) / (2 * s);
b = (y1 + 2 * y2) / (2 * t);
ex = (a - b) * (a - b);
ex += x1 / (4 * s * s);
ex += y1 / (4 * t * t);
h1 = x0 * x2 + (x0 + x2) * x1 / 2 + x1 * (x1 - 1) / 4;
h2 = y0 * y2 + (y0 + y2) * y1 / 2 + y1 * (y1 - 1) / 4;
h1 /= (double) s *(s - 1);
h2 /= (double) t *(t - 1);
en = ex - (h1 / s + h2 / t);
ed = en + h1 + h2;
*pen = en;
*ped = ed;
}
void
destroyaa ()
{
if (aalist == NULL)
return;
freeup (aalist, aanum);
free (aalist);
aalist = NULL;
free2D (&aacnts, aanum);
free2D (&bbcnts, aanum);
aacnts = bbcnts = NULL;
free (aaxadd);
free (ttnum);
free (hest);
free (htest);
free (aafreq);
aanum = -1;
}
void
loadaa (SNP * cupt, int *xindex, int *xtypes, int nrows, int numeg)
{
int k, j, t, a;
int g;
int **ccc, *gg, *rawcol;
double *cc, *dd;
double x0, x1, x2, h1, s, yt;
if (aanum != numeg)
destroyaa ();
aanum = numeg;
if (aalist == NULL) {
ZALLOC (aalist, numeg, char *);
for (k = 0; k < nrows; ++k) {
if (indm == NULL)
break;
j = xtypes[k];
if (j < 0)
continue;
if (j >= numeg)
continue;
if (aalist[j] != NULL)
continue;
t = xindex[k];
aalist[j] = strdup (indm[t]->egroup);
}
}
if (aacnts == NULL) {
aacnts = initarray_2Ddouble (numeg, 3, 0.0);
bbcnts = initarray_2Ddouble (numeg, 2, 0.0);
ZALLOC (ttnum, numeg, double);
ZALLOC (hest, numeg, double);
ZALLOC (htest, numeg, double);
ZALLOC (aafreq, numeg, double);
ZALLOC (aaxadd, numeg, double);
}
clear2D (&aacnts, numeg, 3, 0.0);
clear2D (&bbcnts, numeg, 2, 0.0);
vzero (ttnum, numeg);
ccc = initarray_2Dint (nrows, 2, 0);
if (indm == NULL) {
ZALLOC (rawcol, nrows, int);
getrawcol (rawcol, cupt, xindex, nrows);
for (a = 0; a < nrows; a++) {
g = rawcol[a];
ccc[a][0] = g;
ccc[a][1] = 2 - g;
}
free (rawcol);
}
else {
getrawcolx (ccc, cupt, xindex, nrows, indm);
}
for (k = 0; k < nrows; ++k) {
a = xtypes[k];
if (a < 0)
continue;
if (a >= aanum)
continue;
cc = aacnts[a];
gg = ccc[k];
g = gg[0];
if (g < 0)
continue;
a = intsum (gg, 2);
if (a == 1)
g *= 2; // X and male
++cc[g];
}
for (a = 0; a < aanum; ++a) {
cc = aacnts[a];
dd = bbcnts[a];
dd[0] = 2 * cc[0] + cc[1];
dd[1] = 2 * cc[2] + cc[1];
s = ttnum[a] = asum (cc, 3);
hest[a] = aafreq[a] = -999.0;
if (s < 0.5)
continue;
if (inbreed) {
x0 = cc[0];
x1 = cc[1];
x2 = cc[2];
aafreq[a] = (x1 + 2 * x2) / (2 * s);
/**
b = (y1 + 2*y2) / (2*t) ;
ex = (a-b)*(a-b) ;
ex += x1/(4*s*s) ;
ex += y1/(4*t*t) ;
*/
if (s < 1.5)
continue;
h1 = x0 * x2 + (x0 + x2) * x1 / 2 + x1 * (x1 - 1) / 4;
h1 /= (double) s *(s - 1);
hest[a] = h1;
htest[a] = h1 / s;
aaxadd[a] = x1 / (4 * s * s);
}
else {
x0 = dd[0];
x1 = dd[1];
yt = x0 + x1;
aafreq[a] = x1 / yt;
h1 = x0 * x1 / (yt * (yt - 1.0));
hest[a] = h1;
htest[a] = h1 / yt;
}
}
free2Dint (&ccc, nrows);
}
int
oldf3yyx (double *estmat, SNP * cupt,
int *xindex, int *xtypes, int nrows, int numeg, Indiv ** indmx)
{
int *c1, *c2, *c3, *cc;
int *rawcol;
int k, g, i, a, b, c, t;
int a0, a1, kret;
double ya, yb, yaa, ybb, p1, p2, p3, en, ed;
double z, zz, h1, h2, yt;
double ywt;
int **ccc, *gg, **ccx;
static int ncall = 0;
++ncall;
ccc = initarray_2Dint (nrows, 2, 0);
ccx = initarray_2Dint (numeg + 1, 2, 0);
vzero (estmat, numeg * numeg * numeg);
getrawcolx (ccc, cupt, xindex, nrows, indm);
for (k = 0; k < nrows; ++k) {
a = xtypes[k];
if (a < 0)
continue;
if (a >= numeg)
continue;
g = ccc[k][0];
if (g < 0)
continue;
cc = ccx[a];
ivvp (cc, cc, ccc[k], 2);
}
kret = 1;
for (a = 0; a < numeg; a++) {
for (b = 0; b < numeg; b++) {
for (c = 0; c < numeg; c++) {
if (a == b)
continue;
if (a == c)
continue;
if (c < b)
continue;
c1 = ccx[a];
c2 = ccx[b];
c3 = ccx[c];
ya = (double) c1[0];
yb = (double) c1[1];
z = ya + yb;
yt = ya + yb;
if (yt <= 0) {
kret = -1;
break;
}
p1 = ya / yt;
h1 = ya * yb / (yt * (yt - 1.0));
yaa = (double) c2[0];
ybb = (double) c2[1];
yt = yaa + ybb;
if (yt <= 0) {
kret = -1;
break;
}
p2 = yaa / yt;
h2 = yaa * ybb / (yt * (yt - 1.0));
zz = yaa + ybb;
yaa = (double) c3[0];
ybb = (double) c3[1];
yt = yaa + ybb;
if (yt <= 0) {
kret = -1;
break;
}
p3 = yaa / yt;
en = (p1 - p2) * (p1 - p3);
en -= h1 / z;
if (b == c)
en -= h2 / zz;
bump3 (estmat, a, b, c, numeg, en);
if (b != c)
bump3 (estmat, a, c, b, numeg, en);
t = a * numeg * numeg + b * numeg + c;
if ((t == 18) && (ncall <= 5)) {
printf ("%9.3f ", p1);
printf ("%9.3f ", p2);
printf ("%9.3f ", p3);
printf ("%9.3f ", h1);
printf ("%9.3f ", h1 / z);
printf ("%9.3f ", h2);
printf ("%9.3f ", h2 / zz);
printnl ();
}
}
}
}
if (ncall < 10) {
printf ("zz2 %d\n", kret);
printmat (estmat, numeg * numeg, numeg);
}
free2Dint (&ccc, nrows);
free2Dint (&ccx, numeg + 1);
return kret;
}
void
setindm (Indiv ** indmx)
{
indm = indmx;
}
double gethtest(int popnum)
{
return htest[popnum] ;
}
double gethest(int popnum)
{
return hest[popnum] ;
}
double getfreq(int popnum)
{
return aafreq[popnum] ;
}
double getaax(int popnum)
{
return aaxadd[popnum] ;
}
Computing file changes ...