Scheduled service maintenance on November 22


On Friday, November 22, 2024, between 06:00 CET and 18:00 CET, GIN services will undergo planned maintenance. Extended service interruptions should be expected. We will try to keep downtimes to a minimum, but recommend that users avoid critical tasks, large data uploads, or DOI requests during this time.

We apologize for any inconvenience.

libtube.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. /*
  2. * Copyright 1996-2006 Catherine Loader.
  3. */
  4. #include "mex.h"
  5. /*
  6. * Copyright 1996-2006 Catherine Loader.
  7. */
  8. /*
  9. * Copyright (c) 1998-2006 Catherine Loader.
  10. * This file contains functions to compute the constants
  11. * appearing in the tube formula.
  12. */
  13. #include <stdio.h>
  14. #include <math.h>
  15. #include "tube.h"
  16. static double *fd, *ft;
  17. static int globm, (*wdf)(), use_covar, kap_terms;
  18. int k0_reqd(d,n,uc)
  19. int d, n, uc;
  20. { int m;
  21. m = d*(d+1)+1;
  22. if (uc) return(2*m*m);
  23. else return(2*n*m);
  24. }
  25. void assignk0(z,d,n) /* z should be n*(2*d*d+2*d+2); */
  26. double *z;
  27. int d, n;
  28. { ft = z; z += n*(d*(d+1)+1);
  29. fd = z; z += n*(d*(d+1)+1);
  30. }
  31. /* Residual projection of y to the columns of A,
  32. * (I - A(R^TR)^{-1}A^T)y
  33. * R should be from the QR-decomp. of A.
  34. */
  35. void rproject(y,A,R,n,p)
  36. double *y, *A, *R;
  37. int n, p;
  38. { double v[1+TUBE_MXDIM];
  39. int i, j;
  40. for (i=0; i<p; i++) v[i] = innerprod(&A[i*n],y,n);
  41. qrsolv(R,v,n,p);
  42. for (i=0; i<n; i++)
  43. for (j=0; j<p; j++)
  44. y[i] -= A[j*n+i]*v[j];
  45. }
  46. double k2c(lij,A,m,dd,d)
  47. double *lij, *A;
  48. int m, d, dd;
  49. { int i, j, k, l;
  50. double sum, *bk, v[TUBE_MXDIM];
  51. for (i=0; i<dd*d; i++)
  52. chol_hsolve(fd,&lij[i*m],m,dd+1);
  53. for (i=0; i<dd*d; i++)
  54. for (j=0; j<dd*d; j++)
  55. lij[i*m+j+d+1] -= innerprod(&lij[i*m],&lij[j*m],dd+1);
  56. sum = 0;
  57. for (i=0; i<dd; i++)
  58. for (j=0; j<i; j++)
  59. { bk = &lij[i*d*m + j*d + d+1];
  60. for (k=0; k<dd; k++)
  61. { v[0] = 0;
  62. for (l=0; l<dd; l++) v[l+1] = bk[k*m+l];
  63. chol_solve(fd,v,m,dd+1);
  64. for (l=0; l<dd; l++) bk[k*m+l] = v[l+1];
  65. }
  66. for (k=0; k<dd; k++)
  67. { v[0] = 0;
  68. for (l=0; l<dd; l++) v[l+1] = bk[l*m+k];
  69. chol_solve(fd,v,m,dd+1);
  70. for (l=0; l<dd; l++) bk[l*m+k] = v[l+1];
  71. }
  72. sum += bk[i*m+j] - bk[j*m+i];
  73. }
  74. return(sum*fd[0]*fd[0]);
  75. }
  76. double k2x(lij,A,m,d,dd)
  77. double *lij, *A;
  78. int m, d, dd;
  79. { int i, j, k;
  80. double s, v[1+TUBE_MXDIM], *ll;
  81. /* residual projections of lij onto A = [l,l1,...,ld] */
  82. for (i=0; i<d; i++)
  83. for (j=i; j<d; j++)
  84. { ll = &lij[(i*dd+j)*m];
  85. rproject(ll,A,fd,m,d+1);
  86. if (i!=j) memcpy(&lij[(j*dd+i)*m],ll,m*sizeof(double));
  87. }
  88. /* compute lij[j][i] = e_i^T (A^T A)^{-1} B_j^T */
  89. for (k=0; k<m; k++)
  90. for (j=0; j<d; j++)
  91. { v[0] = 0;
  92. for (i=0; i<d; i++) v[i+1] = lij[(j*dd+i)*m+k];
  93. qrsolv(fd,v,m,d+1);
  94. for (i=0; i<d; i++) lij[(j*dd+i)*m+k] = v[i+1];
  95. }
  96. /* finally, add up to get the kappa2 term */
  97. s = 0;
  98. for (j=0; j<d; j++)
  99. for (k=0; k<j; k++)
  100. s += innerprod(&lij[(j*dd+j)*m],&lij[(k*dd+k)*m],m)
  101. - innerprod(&lij[(j*dd+k)*m],&lij[(k*dd+j)*m],m);
  102. return(s*fd[0]*fd[0]);
  103. }
  104. void d2c(ll,nn,li,ni,lij,nij,M,m,dd,d)
  105. double *ll, *nn, *li, *ni, *lij, *nij, *M;
  106. int m, dd, d;
  107. { int i, j, k, l, t, u, v, w;
  108. double z;
  109. for (i=0; i<dd; i++)
  110. for (j=0; j<dd; j++)
  111. { for (k=0; k<d; k++)
  112. { for (l=0; l<d; l++)
  113. { z = M[i*d+k]*M[j*d+l];
  114. if (z != 0.0)
  115. { nij[(i*d+j)*m] += z*lij[(k*d+l)*m];
  116. for (t=0; t<d; t++) /* need d, not dd here */
  117. for (u=0; u<d; u++)
  118. nij[(i*d+j)*m+t+1] += z*M[t*d+u]*lij[(k*d+l)*m+u+1];
  119. for (t=0; t<dd; t++)
  120. for (u=0; u<dd; u++)
  121. { for (v=0; v<d; v++)
  122. for (w=0; w<d; w++)
  123. nij[(i*d+j)*m+(t*d+u)+d+1] +=
  124. z*M[t*d+v]*M[u*d+w]*lij[(k*d+l)*m+(v*d+w)+d+1];
  125. for (v=0; v<d; v++)
  126. nij[(i*d+j)*m+(t*d+u)+d+1] += z*M[(v+1)*d*d+t*d+u]*lij[(k*d+l)*m+v+1];
  127. }
  128. }
  129. }
  130. z = M[(k+1)*d*d+i*d+j];
  131. if (z!=0.0)
  132. { nij[(i*d+j)*m] += z*li[k*m];
  133. for (t=0; t<d; t++)
  134. for (u=0; u<d; u++)
  135. nij[(i*d+j)*m+t+1] += z*M[t*d+u]*li[k*m+u+1];
  136. for (t=0; t<dd; t++)
  137. for (u=0; u<dd; u++)
  138. { for (v=0; v<d; v++)
  139. for (w=0; w<d; w++)
  140. nij[(i*d+j)*m+(t*d+u)+d+1] += z*M[t*d+v]*M[u*d+w]*lij[(v*d+w)*m+k+1];
  141. for (v=0; v<d; v++)
  142. nij[(i*d+j)*m+(t*d+u)+d+1] += z*M[(v+1)*d*d+t*d+u]*li[k*m+v+1];
  143. }
  144. }
  145. }
  146. }
  147. }
  148. void d2x(li,lij,nij,M,m,dd,d)
  149. double *li, *lij, *nij, *M;
  150. int m, dd, d;
  151. { int i, j, k, l, z;
  152. double t;
  153. for (i=0; i<dd; i++)
  154. for (j=0; j<dd; j++)
  155. { for (k=0; k<d; k++)
  156. { for (l=0; l<d; l++)
  157. { t = M[i*d+k] * M[j*d+l];
  158. if (t != 0.0)
  159. { for (z=0; z<m; z++)
  160. nij[(i*d+j)*m+z] += t*lij[(k*d+l)*m+z];
  161. }
  162. }
  163. t = M[(k+1)*d*d+i*d+j];
  164. if (t!=0.0)
  165. for (z=0; z<m; z++)
  166. nij[(i*d+j)*m+z] += t*li[k*m+z];
  167. }
  168. }
  169. }
  170. int k0x(x,d,kap,M)
  171. double *x, *kap, *M;
  172. int d;
  173. { double det, *lij, *nij, z;
  174. int j, m, r;
  175. r = 1 + ((d>=2) & (kap_terms >= 3));
  176. m = globm = wdf(x,ft,r);
  177. memcpy(fd,ft,m*(d+1)*sizeof(double));
  178. if (use_covar) chol_dec(fd,m,d+1);
  179. else qr(fd,m,d+1,NULL);
  180. det = 1;
  181. for (j=1; j<=d; j++)
  182. det *= fd[j*(m+1)]/fd[0];
  183. kap[0] = det;
  184. if (kap_terms == 1) return(1);
  185. kap[1] = 0.0;
  186. if ((kap_terms == 2) | (d<=1)) return(2);
  187. lij = &ft[(d+1)*m];
  188. nij = &fd[(d+1)*m];
  189. memcpy(nij,lij,m*d*d*sizeof(double));
  190. z = (use_covar) ? k2c(nij,ft,m,d,d) : k2x(nij,ft,m,d,d);
  191. kap[2] = z*det;
  192. if ((kap_terms == 3) | (d==2)) return(3);
  193. kap[3] = 0;
  194. return(4);
  195. }
  196. void d1c(li,ni,m,d,M)
  197. double *li, *ni, *M;
  198. int m, d;
  199. { int i, j, k, l;
  200. double t;
  201. fd[0] = ft[0];
  202. for (i=0; i<d; i++)
  203. { t = 0;
  204. for (j=0; j<d; j++) t += M[i*d+j]*li[j*m];
  205. fd[i+1] = ni[i*m] = t;
  206. for (j=0; j<d; j++)
  207. { t = 0;
  208. for (k=0; k<d; k++)
  209. for (l=0; l<d; l++)
  210. t += li[k*m+l+1] * M[i*d+k] * M[j*d+l];
  211. ni[i*m+j+1] = t;
  212. }
  213. }
  214. }
  215. void d1x(li,ni,m,d,M)
  216. double *li, *ni, *M;
  217. int m, d;
  218. { int i, j, k;
  219. memcpy(fd,ft,m*sizeof(double));
  220. setzero(ni,m*d);
  221. for (j=0; j<d; j++)
  222. for (k=0; k<d; k++)
  223. if (M[j*d+k]!=0)
  224. for (i=0; i<m; i++) ni[j*m+i] += M[j*d+k]*li[k*m+i];
  225. }
  226. int l1x(x,d,lap,M)
  227. double *x, *lap, *M;
  228. int d;
  229. { double det, sumcj, *u, v[TUBE_MXDIM];
  230. double *ll, *li, *lij, *ni, *nij;
  231. int i, j, m;
  232. if (kap_terms<=1) return(0);
  233. m = globm;
  234. li = &ft[m]; lij = &ft[(d+1)*m];
  235. ni = &fd[m]; nij = &fd[(d+1)*m];
  236. setzero(ni,m*d);
  237. setzero(nij,m*d*d);
  238. if (use_covar) d1c(li,ni,m,d,M);
  239. else d1x(li,ni,m,d,M);
  240. /* the last (d+1) columns of nij are free, use for an extra copy of ni */
  241. ll = &fd[d*d*m];
  242. u = &ll[d*m];
  243. if (use_covar)
  244. memcpy(u,&ni[(d-1)*m],d*sizeof(double)); /* cov(ld, (l,l1,...ld-1)) */
  245. else
  246. memcpy(ll,fd,(d+1)*m*sizeof(double));
  247. if (use_covar) chol_dec(fd,m,d+1);
  248. else qr(fd,m,d+1,NULL);
  249. det = 1;
  250. for (j=1; j<d; j++)
  251. det *= fd[(m+1)*j]/fd[0];
  252. lap[0] = det;
  253. if ((kap_terms==2) | (d<=1)) return(1);
  254. sumcj = 0.0;
  255. if (use_covar)
  256. { d2c(ft,fd,li,ni,lij,nij,M,m,d-1,d);
  257. chol_solve(fd,u,m,d);
  258. for (i=0; i<d-1; i++)
  259. { v[0] = 0;
  260. for (j=0; j<d-1; j++)
  261. v[j+1] = nij[(i*d+j)*m+d] - innerprod(u,&nij[(i*d+j)*m],d);
  262. chol_solve(fd,v,m,d);
  263. sumcj -= v[i+1];
  264. }
  265. }
  266. else
  267. { d2x(li,lij,nij,M,m,d-1,d);
  268. rproject(u,ll,fd,m,d);
  269. for (i=0; i<d-1; i++)
  270. { v[0] = 0;
  271. for (j=0; j<d-1; j++) v[j+1] = innerprod(&nij[(i*d+j)*m],u,m);
  272. qrsolv(fd,v,m,d);
  273. sumcj -= v[i+1];
  274. }
  275. }
  276. lap[1] = sumcj*det*fd[0]/fd[(m+1)*d];
  277. if ((kap_terms==3) | (d==2)) return(2);
  278. if (use_covar) lap[2] = k2c(nij,ll,m,d-1,d)*det;
  279. else lap[2] = k2x(nij,ll,m,d-1,d)*det;
  280. return(3);
  281. }
  282. int m0x(x,d,m0,M)
  283. double *x, *m0, *M;
  284. int d;
  285. { double det, *li, *ni, *lij, *nij, *ll, *u1, *u2;
  286. double om, so, co, sumcj, v[TUBE_MXDIM];
  287. int m, i, j;
  288. if ((kap_terms<=2) | (d<=1)) return(0);
  289. m = globm;
  290. li = &ft[m]; lij = &ft[(d+1)*m];
  291. ni = &fd[m]; nij = &fd[(d+1)*m];
  292. setzero(ni,m*d);
  293. setzero(nij,m*d*d);
  294. if (use_covar) d1c(li,ni,m,d,M);
  295. else d1x(li,ni,m,d,M);
  296. /* the last (d+1) columns of nij are free, use for an extra copy of ni */
  297. ll = &fd[d*d*m];
  298. u1 = &ll[d*m];
  299. u2 = &ll[(d-1)*m];
  300. if (use_covar)
  301. { memcpy(u1,&ni[(d-1)*m],d*sizeof(double));
  302. memcpy(u2,&ni[(d-2)*m],d*sizeof(double));
  303. }
  304. else
  305. memcpy(ll,fd,(d+1)*m*sizeof(double));
  306. if (use_covar) chol_dec(fd,m,d+1);
  307. else qr(fd,m,d+1,NULL);
  308. det = 1;
  309. for (j=1; j<d-1; j++)
  310. det *= fd[j*(m+1)]/fd[0];
  311. om = atan2(fd[d*(m+1)],-fd[d*(m+1)-1]);
  312. m0[0] = det*om;
  313. if ((kap_terms==3) | (d==2)) return(1);
  314. so = sin(om)/fd[d*(m+1)];
  315. co = (1-cos(om))/fd[(d-1)*(m+1)];
  316. sumcj = 0.0;
  317. if (use_covar)
  318. { d2c(ft,fd,li,ni,lij,nij,M,m,d-2,d);
  319. chol_solve(fd,u1,m,d);
  320. chol_solve(fd,u2,m,d-1);
  321. for (i=0; i<d-2; i++)
  322. { v[0] = 0;
  323. for (j=0; j<d-2; j++)
  324. v[j+1] =
  325. so*(nij[(i*d+j)*m+d]-innerprod(u1,&nij[(i*d+j)*m],d))
  326. +co*(nij[(i*d+j)*m+d-1]-innerprod(u2,&nij[(i*d+j)*m],d-1));
  327. qrsolv(fd,v,m,d-1);
  328. sumcj -= v[i+1];
  329. }
  330. }
  331. else
  332. { d2x(li,lij,nij,M,m,d-2,d);
  333. rproject(u1,ll,fd,m,d);
  334. rproject(u2,ll,fd,m,d-1); /* now, u1, u2 are unnormalized n1*, n2* */
  335. for (i=0; i<m; i++)
  336. u1[i] = so*u1[i] + co*u2[i]; /* for n1*, n2* */
  337. for (i=0; i<d-2; i++)
  338. { v[0] = 0;
  339. for (j=0; j<d-2; j++)
  340. v[j+1] = innerprod(&nij[(i*d+j)*m],u1,m);
  341. qrsolv(fd,v,m,d-1);
  342. sumcj -= v[i+1];
  343. }
  344. }
  345. m0[1] = sumcj*det*fd[0];
  346. return(2);
  347. }
  348. int n0x(x,d,n0,M)
  349. double *x, *n0, *M;
  350. int d;
  351. { double det, *li, *ni, *a0, *a1, *a2;
  352. int j, m;
  353. if ((kap_terms <= 3) | (d <= 2)) return(0);
  354. m = globm;
  355. li = &ft[m];
  356. ni = &fd[m];
  357. if (use_covar) d1c(li,ni,m,d,M);
  358. else d1x(li,ni,m,d,M);
  359. det = 1;
  360. if (use_covar) chol_dec(fd,m,d+1);
  361. else qr(fd,m,d+1,NULL);
  362. for (j=1; j<d-2; j++)
  363. det *= fd[j*(m+1)]/fd[0];
  364. a0 = &ni[(d-3)*m+d-2];
  365. a1 = &ni[(d-2)*m+d-2];
  366. a2 = &ni[(d-1)*m+d-2];
  367. a0[0] = a1[1]*a2[2];
  368. a0[1] =-a1[0]*a2[2];
  369. a0[2] = a1[0]*a2[1]-a1[1]*a2[0];
  370. a1[0] = 0;
  371. a1[1] = a2[2];
  372. a1[2] =-a2[1];
  373. a2[0] = a2[1] = 0.0; a2[2] = 1.0;
  374. rn3(a0); rn3(a1);
  375. n0[0] = det*sptarea(a0,a1,a2);
  376. return(1);
  377. }
  378. int kodf(ll,ur,mg,kap,lap)
  379. double *ll, *ur, *kap, *lap;
  380. int *mg;
  381. { double x[1], *l0, *l1, t, sum;
  382. int i, j, n;
  383. sum = 0.0;
  384. for (i=0; i<=mg[0]; i++)
  385. { if (i&1) { l1 = fd; l0 = ft; }
  386. else { l1 = ft; l0 = fd; }
  387. x[0] = ll[0] + (ur[0]-ll[0])*i/mg[0];
  388. n = wdf(x,l0,0);
  389. t = sqrt(innerprod(l0,l0,n));
  390. for (j=0; j<n; j++) l0[j] /= t;
  391. if (i>0)
  392. { t = 0.0;
  393. for (j=0; j<n; j++) t += (l1[j]-l0[j])*(l1[j]-l0[j]);
  394. sum += 2*asin(sqrt(t)/2);
  395. }
  396. }
  397. kap[0] = sum;
  398. if (kap_terms<=1) return(1);
  399. kap[1] = 0.0;
  400. lap[0] = 2.0;
  401. return(2);
  402. }
  403. int tube_constants(f,d,m,ev,mg,fl,kap,wk,terms,uc)
  404. double *fl, *kap, *wk;
  405. int d, m, ev, *mg, (*f)(), terms, uc;
  406. { int aw, deb=0;
  407. double k0[4], l0[3], m0[2], n0[1], z[TUBE_MXDIM];
  408. wdf = f;
  409. aw = (wk==NULL);
  410. if (aw) {
  411. wk = (double *)calloc(k0_reqd(d,m,uc),sizeof(double));
  412. if ( wk == NULL ) {
  413. printf("Problem allocating memory for wk\n");fflush(stdout);
  414. }
  415. }
  416. assignk0(wk,d,m);
  417. k0[0] = k0[1] = k0[2] = k0[3] = 0.0;
  418. l0[0] = l0[1] = l0[2] = 0.0;
  419. m0[0] = m0[1] = 0.0;
  420. n0[0] = 0.0;
  421. use_covar = uc;
  422. kap_terms = terms;
  423. if ((kap_terms <=0) | (kap_terms >= 5))
  424. mut_printf("Warning: terms = %2d\n",kap_terms);
  425. switch(ev)
  426. {
  427. case IMONTE:
  428. monte(k0x,fl,&fl[d],d,k0,mg[0]);
  429. break;
  430. case ISPHERIC:
  431. if (d==2) integ_disc(k0x,l1x,fl,k0,l0,mg);
  432. if (d==3) integ_sphere(k0x,l1x,fl,k0,l0,mg);
  433. break;
  434. case ISIMPSON:
  435. if (use_covar) simpson4(k0x,l1x,m0x,n0x,fl,&fl[d],d,k0,l0,m0,n0,mg,z);
  436. else simpson4(k0x,l1x,m0x,n0x,fl,&fl[d],d,k0,l0,m0,n0,mg,z);
  437. break;
  438. case IDERFREE:
  439. kodf(fl,&fl[d],mg,k0,l0);
  440. break;
  441. default:
  442. mut_printf("Unknown integration type in tube_constants().\n");
  443. }
  444. if (deb>0)
  445. { mut_printf("constants:\n");
  446. mut_printf(" k0: %8.5f %8.5f %8.5f %8.5f\n",k0[0],k0[1],k0[2],k0[3]);
  447. mut_printf(" l0: %8.5f %8.5f %8.5f\n",l0[0],l0[1],l0[2]);
  448. mut_printf(" m0: %8.5f %8.5f\n",m0[0],m0[1]);
  449. mut_printf(" n0: %8.5f\n",n0[0]);
  450. if (d==2) mut_printf(" check: %8.5f\n",(k0[0]+k0[2]+l0[1]+m0[0])/(2*PI));
  451. if (d==3) mut_printf(" check: %8.5f\n",(l0[0]+l0[2]+m0[1]+n0[0])/(4*PI));
  452. }
  453. if (aw) free(wk);
  454. kap[0] = k0[0];
  455. if (kap_terms==1) return(1);
  456. kap[1] = l0[0]/2;
  457. if ((kap_terms==2) | (d==1)) return(2);
  458. kap[2] = (k0[2]+l0[1]+m0[0])/(2*PI);
  459. if ((kap_terms==3) | (d==2)) return(3);
  460. kap[3] = (l0[2]+m0[1]+n0[0])/(4*PI);
  461. return(4);
  462. }
  463. /*
  464. * Copyright 1996-2006 Catherine Loader.
  465. */
  466. /*
  467. * Copyright (c) 1998-2006 Catherine Loader.
  468. *
  469. * Computes the critical values from constants kappa0 etc
  470. * and significance level.
  471. */
  472. #include <math.h>
  473. #include "tube.h"
  474. #define LOGPI 1.144729885849400174143427
  475. /* area(d) = 2 pi^(d/2) / Gamma(d/2)
  476. * = surface area of unit sphere in R^d
  477. */
  478. static double A[10] =
  479. { 1, /* d=0, whatever */
  480. 2,
  481. 6.2831853071795864770, /* 2*pi */
  482. 12.566370614359172954, /* 4*pi */
  483. 19.739208802178717238, /* 2*pi^2 */
  484. 26.318945069571622985, /* 8/3*pi^2 */
  485. 31.006276680299820177, /* pi^3 */
  486. 33.073361792319808190, /* 16/15*pi^3 */
  487. 32.469697011334145747, /* 1/3*pi^4 */
  488. 29.686580124648361825 /* 32/105*pi^4 */
  489. };
  490. double area(d)
  491. int d;
  492. { if (d<10) return(A[d]);
  493. return(2*exp(d*LOGPI/2.0-mut_lgammai(d)));
  494. }
  495. double tailp_uniform(c,k0,m,d,s,n)
  496. double c, *k0, n;
  497. int m, d, s;
  498. { int i;
  499. double p;
  500. p = 0.0;
  501. for (i=0; i<m; i++) if (k0[i] != 0.0)
  502. p += k0[i] * ibeta(1-c*c,(n-d+i-1)/2.0,(d+1-i)/2.0) / area(d+1-i);
  503. return( (s==TWO_SIDED) ? 2*p : p );
  504. }
  505. double tailp_gaussian(c,k0,m,d,s,n)
  506. double c, *k0, n;
  507. int m, d, s;
  508. { int i;
  509. double p;
  510. p = 0.0;
  511. for (i=0; i<m; i++) if (k0[i] != 0.0)
  512. p += k0[i] * (1-pchisq(c*c,(double) d+1-i)) / area(d+1-i);
  513. return( (s==TWO_SIDED) ? 2*p : p );
  514. }
  515. double tailp_tprocess(c,k0,m,d,s,n)
  516. double c, *k0, n;
  517. int m, d, s;
  518. { int i;
  519. double p;
  520. p = 0.0;
  521. for (i=0; i<m; i++) if (k0[i] != 0.0)
  522. p += k0[i] * (1-pf(c*c/(d+1-i),(double) d+1-i, n)) / area(d+1-i);
  523. return( (s==TWO_SIDED) ? 2*p : p );
  524. }
  525. double taild_uniform(c,k0,m,d,s,n)
  526. double c, *k0, n;
  527. int m, d, s;
  528. { int i;
  529. double p;
  530. p = 0.0;
  531. for (i=0; i<m; i++) if (k0[i] != 0.0)
  532. p += k0[i] * 2*c*dbeta(1-c*c,(n-d+i-1)/2.0,(d+1-i)/2.0,0) / area(d+1-i);
  533. return( (s==TWO_SIDED) ? 2*p : p );
  534. }
  535. double taild_gaussian(c,k0,m,d,s,n)
  536. double c, *k0, n;
  537. int m, d, s;
  538. { int i;
  539. double p;
  540. p = 0.0;
  541. for (i=0; i<m; i++) if (k0[i] != 0.0)
  542. p += k0[i] * 2*c*dchisq(c*c,(double) d+1-i,0) / area(d+1-i);
  543. return( (s==TWO_SIDED) ? 2*p : p );
  544. }
  545. double taild_tprocess(c,k0,m,d,s,n)
  546. double c, *k0, n;
  547. int m, d, s;
  548. { int i;
  549. double p;
  550. p = 0.0;
  551. for (i=0; i<m; i++) if (k0[i] != 0.0)
  552. p += k0[i] * 2*c*df(c*c/(d+1-i),(double) d+1-i, n,0) / ((d+1-i)*area(d+1-i));
  553. return( (s==TWO_SIDED) ? 2*p : p );
  554. }
  555. double tailp(c,k0,m,d,s,nu, process)
  556. double c, *k0, nu;
  557. int m, d, s, process;
  558. { switch(process)
  559. { case UNIF: return(tailp_uniform(c,k0,m,d,s,nu));
  560. case GAUSS: return(tailp_gaussian(c,k0,m,d,s,nu));
  561. case TPROC: return(tailp_tprocess(c,k0,m,d,s,nu));
  562. }
  563. mut_printf("taild: unknown process.\n");
  564. return(0.0);
  565. }
  566. double taild(c,k0,m,d,s,nu, process)
  567. double c, *k0, nu;
  568. int m, d, s, process;
  569. { switch(process)
  570. { case UNIF: return(taild_uniform(c,k0,m,d,s,nu));
  571. case GAUSS: return(taild_gaussian(c,k0,m,d,s,nu));
  572. case TPROC: return(taild_tprocess(c,k0,m,d,s,nu));
  573. }
  574. mut_printf("taild: unknown process.\n");
  575. return(0.0);
  576. }
  577. double critval(alpha,k0,m,d,s,nu,process)
  578. double alpha, *k0, nu;
  579. int m, d, s, process;
  580. { double c, cn, c0, c1, tp, td;
  581. int j, maxit;
  582. double (*tpf)(), (*tdf)();
  583. maxit = 20;
  584. if (m<0)
  585. { mut_printf("critval: no terms?\n");
  586. return(2.0);
  587. }
  588. if (m>d+1) m = d+1;
  589. if ((alpha<=0) | (alpha>=1))
  590. { mut_printf("critval: invalid alpha %8.5f\n",alpha);
  591. return(2.0);
  592. }
  593. if (alpha>0.5)
  594. mut_printf("critval: A mighty large tail probability alpha=%8.5f\n",alpha);
  595. if (m==0) { d = 0; k0[0] = 1; m = 1; }
  596. switch(process)
  597. { case UNIF:
  598. c = 0.5; c0 = 0.0; c1 = 1.0;
  599. tpf = tailp_uniform;
  600. tdf = taild_uniform;
  601. break;
  602. case GAUSS:
  603. c = 2.0; c0 = 0.0; c1 = 0.0;
  604. tpf = tailp_gaussian;
  605. tdf = taild_gaussian;
  606. break;
  607. case TPROC:
  608. c = 2.0; c0 = 0.0; c1 = 0.0;
  609. tpf = tailp_tprocess;
  610. tdf = taild_tprocess;
  611. break;
  612. default:
  613. mut_printf("critval: unknown process.\n");
  614. return(0.0);
  615. }
  616. for (j=0; j<maxit; j++)
  617. { tp = tpf(c,k0,m,d,s,nu)-alpha;
  618. td = tdf(c,k0,m,d,s,nu);
  619. if (tp>0) c0 = c;
  620. if (tp<0) c1 = c;
  621. cn = c + tp/td;
  622. if (cn<c0) cn = (c+c0)/2;
  623. if ((c1>0.0) && (cn>c1)) cn = (c+c1)/2;
  624. c = cn;
  625. if (fabs(tp/alpha)<1.0e-10) return(c);
  626. }
  627. return(c);
  628. }