/* * Copyright 1996-2006 Catherine Loader. */ #include "mex.h" /* * Copyright 1996-2006 Catherine Loader. */ /* * Copyright (c) 1998-2006 Catherine Loader. * This file contains functions to compute the constants * appearing in the tube formula. */ #include #include #include "tube.h" static double *fd, *ft; static int globm, (*wdf)(), use_covar, kap_terms; int k0_reqd(d,n,uc) int d, n, uc; { int m; m = d*(d+1)+1; if (uc) return(2*m*m); else return(2*n*m); } void assignk0(z,d,n) /* z should be n*(2*d*d+2*d+2); */ double *z; int d, n; { ft = z; z += n*(d*(d+1)+1); fd = z; z += n*(d*(d+1)+1); } /* Residual projection of y to the columns of A, * (I - A(R^TR)^{-1}A^T)y * R should be from the QR-decomp. of A. */ void rproject(y,A,R,n,p) double *y, *A, *R; int n, p; { double v[1+TUBE_MXDIM]; int i, j; for (i=0; i=2) & (kap_terms >= 3)); m = globm = wdf(x,ft,r); memcpy(fd,ft,m*(d+1)*sizeof(double)); if (use_covar) chol_dec(fd,m,d+1); else qr(fd,m,d+1,NULL); det = 1; for (j=1; j<=d; j++) det *= fd[j*(m+1)]/fd[0]; kap[0] = det; if (kap_terms == 1) return(1); kap[1] = 0.0; if ((kap_terms == 2) | (d<=1)) return(2); lij = &ft[(d+1)*m]; nij = &fd[(d+1)*m]; memcpy(nij,lij,m*d*d*sizeof(double)); z = (use_covar) ? k2c(nij,ft,m,d,d) : k2x(nij,ft,m,d,d); kap[2] = z*det; if ((kap_terms == 3) | (d==2)) return(3); kap[3] = 0; return(4); } void d1c(li,ni,m,d,M) double *li, *ni, *M; int m, d; { int i, j, k, l; double t; fd[0] = ft[0]; for (i=0; i0) { t = 0.0; for (j=0; j= 5)) mut_printf("Warning: terms = %2d\n",kap_terms); switch(ev) { case IMONTE: monte(k0x,fl,&fl[d],d,k0,mg[0]); break; case ISPHERIC: if (d==2) integ_disc(k0x,l1x,fl,k0,l0,mg); if (d==3) integ_sphere(k0x,l1x,fl,k0,l0,mg); break; case ISIMPSON: if (use_covar) simpson4(k0x,l1x,m0x,n0x,fl,&fl[d],d,k0,l0,m0,n0,mg,z); else simpson4(k0x,l1x,m0x,n0x,fl,&fl[d],d,k0,l0,m0,n0,mg,z); break; case IDERFREE: kodf(fl,&fl[d],mg,k0,l0); break; default: mut_printf("Unknown integration type in tube_constants().\n"); } if (deb>0) { mut_printf("constants:\n"); mut_printf(" k0: %8.5f %8.5f %8.5f %8.5f\n",k0[0],k0[1],k0[2],k0[3]); mut_printf(" l0: %8.5f %8.5f %8.5f\n",l0[0],l0[1],l0[2]); mut_printf(" m0: %8.5f %8.5f\n",m0[0],m0[1]); mut_printf(" n0: %8.5f\n",n0[0]); if (d==2) mut_printf(" check: %8.5f\n",(k0[0]+k0[2]+l0[1]+m0[0])/(2*PI)); if (d==3) mut_printf(" check: %8.5f\n",(l0[0]+l0[2]+m0[1]+n0[0])/(4*PI)); } if (aw) free(wk); kap[0] = k0[0]; if (kap_terms==1) return(1); kap[1] = l0[0]/2; if ((kap_terms==2) | (d==1)) return(2); kap[2] = (k0[2]+l0[1]+m0[0])/(2*PI); if ((kap_terms==3) | (d==2)) return(3); kap[3] = (l0[2]+m0[1]+n0[0])/(4*PI); return(4); } /* * Copyright 1996-2006 Catherine Loader. */ /* * Copyright (c) 1998-2006 Catherine Loader. * * Computes the critical values from constants kappa0 etc * and significance level. */ #include #include "tube.h" #define LOGPI 1.144729885849400174143427 /* area(d) = 2 pi^(d/2) / Gamma(d/2) * = surface area of unit sphere in R^d */ static double A[10] = { 1, /* d=0, whatever */ 2, 6.2831853071795864770, /* 2*pi */ 12.566370614359172954, /* 4*pi */ 19.739208802178717238, /* 2*pi^2 */ 26.318945069571622985, /* 8/3*pi^2 */ 31.006276680299820177, /* pi^3 */ 33.073361792319808190, /* 16/15*pi^3 */ 32.469697011334145747, /* 1/3*pi^4 */ 29.686580124648361825 /* 32/105*pi^4 */ }; double area(d) int d; { if (d<10) return(A[d]); return(2*exp(d*LOGPI/2.0-mut_lgammai(d))); } double tailp_uniform(c,k0,m,d,s,n) double c, *k0, n; int m, d, s; { int i; double p; p = 0.0; for (i=0; id+1) m = d+1; if ((alpha<=0) | (alpha>=1)) { mut_printf("critval: invalid alpha %8.5f\n",alpha); return(2.0); } if (alpha>0.5) mut_printf("critval: A mighty large tail probability alpha=%8.5f\n",alpha); if (m==0) { d = 0; k0[0] = 1; m = 1; } switch(process) { case UNIF: c = 0.5; c0 = 0.0; c1 = 1.0; tpf = tailp_uniform; tdf = taild_uniform; break; case GAUSS: c = 2.0; c0 = 0.0; c1 = 0.0; tpf = tailp_gaussian; tdf = taild_gaussian; break; case TPROC: c = 2.0; c0 = 0.0; c1 = 0.0; tpf = tailp_tprocess; tdf = taild_tprocess; break; default: mut_printf("critval: unknown process.\n"); return(0.0); } for (j=0; j0) c0 = c; if (tp<0) c1 = c; cn = c + tp/td; if (cn0.0) && (cn>c1)) cn = (c+c1)/2; c = cn; if (fabs(tp/alpha)<1.0e-10) return(c); } return(c); }