Mercurial > repos > vipints > rdiff
diff rDiff/src/locfit/Source/libtube.c @ 0:0f80a5141704
version 0.3 uploaded
author | vipints |
---|---|
date | Thu, 14 Feb 2013 23:38:36 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rDiff/src/locfit/Source/libtube.c Thu Feb 14 23:38:36 2013 -0500 @@ -0,0 +1,708 @@ +/* + * 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 <stdio.h> +#include <math.h> +#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<p; i++) v[i] = innerprod(&A[i*n],y,n); + qrsolv(R,v,n,p); + for (i=0; i<n; i++) + for (j=0; j<p; j++) + y[i] -= A[j*n+i]*v[j]; +} + +double k2c(lij,A,m,dd,d) +double *lij, *A; +int m, d, dd; +{ int i, j, k, l; + double sum, *bk, v[TUBE_MXDIM]; + + for (i=0; i<dd*d; i++) + chol_hsolve(fd,&lij[i*m],m,dd+1); + for (i=0; i<dd*d; i++) + for (j=0; j<dd*d; j++) + lij[i*m+j+d+1] -= innerprod(&lij[i*m],&lij[j*m],dd+1); + + sum = 0; + for (i=0; i<dd; i++) + for (j=0; j<i; j++) + { bk = &lij[i*d*m + j*d + d+1]; + for (k=0; k<dd; k++) + { v[0] = 0; + for (l=0; l<dd; l++) v[l+1] = bk[k*m+l]; + chol_solve(fd,v,m,dd+1); + for (l=0; l<dd; l++) bk[k*m+l] = v[l+1]; + } + for (k=0; k<dd; k++) + { v[0] = 0; + for (l=0; l<dd; l++) v[l+1] = bk[l*m+k]; + chol_solve(fd,v,m,dd+1); + for (l=0; l<dd; l++) bk[l*m+k] = v[l+1]; + } + sum += bk[i*m+j] - bk[j*m+i]; + } + return(sum*fd[0]*fd[0]); +} + +double k2x(lij,A,m,d,dd) +double *lij, *A; +int m, d, dd; +{ int i, j, k; + double s, v[1+TUBE_MXDIM], *ll; + +/* residual projections of lij onto A = [l,l1,...,ld] */ + for (i=0; i<d; i++) + for (j=i; j<d; j++) + { ll = &lij[(i*dd+j)*m]; + rproject(ll,A,fd,m,d+1); + if (i!=j) memcpy(&lij[(j*dd+i)*m],ll,m*sizeof(double)); + } + +/* compute lij[j][i] = e_i^T (A^T A)^{-1} B_j^T */ + for (k=0; k<m; k++) + for (j=0; j<d; j++) + { v[0] = 0; + for (i=0; i<d; i++) v[i+1] = lij[(j*dd+i)*m+k]; + qrsolv(fd,v,m,d+1); + for (i=0; i<d; i++) lij[(j*dd+i)*m+k] = v[i+1]; + } + +/* finally, add up to get the kappa2 term */ + s = 0; + for (j=0; j<d; j++) + for (k=0; k<j; k++) + s += innerprod(&lij[(j*dd+j)*m],&lij[(k*dd+k)*m],m) + - innerprod(&lij[(j*dd+k)*m],&lij[(k*dd+j)*m],m); + + return(s*fd[0]*fd[0]); +} + +void d2c(ll,nn,li,ni,lij,nij,M,m,dd,d) +double *ll, *nn, *li, *ni, *lij, *nij, *M; +int m, dd, d; +{ int i, j, k, l, t, u, v, w; + double z; + + for (i=0; i<dd; i++) + for (j=0; j<dd; j++) + { for (k=0; k<d; k++) + { for (l=0; l<d; l++) + { z = M[i*d+k]*M[j*d+l]; + if (z != 0.0) + { nij[(i*d+j)*m] += z*lij[(k*d+l)*m]; + for (t=0; t<d; t++) /* need d, not dd here */ + for (u=0; u<d; u++) + nij[(i*d+j)*m+t+1] += z*M[t*d+u]*lij[(k*d+l)*m+u+1]; + for (t=0; t<dd; t++) + for (u=0; u<dd; u++) + { for (v=0; v<d; v++) + for (w=0; w<d; w++) + nij[(i*d+j)*m+(t*d+u)+d+1] += + z*M[t*d+v]*M[u*d+w]*lij[(k*d+l)*m+(v*d+w)+d+1]; + for (v=0; v<d; v++) + 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]; + } + } + } + + z = M[(k+1)*d*d+i*d+j]; + if (z!=0.0) + { nij[(i*d+j)*m] += z*li[k*m]; + for (t=0; t<d; t++) + for (u=0; u<d; u++) + nij[(i*d+j)*m+t+1] += z*M[t*d+u]*li[k*m+u+1]; + for (t=0; t<dd; t++) + for (u=0; u<dd; u++) + { for (v=0; v<d; v++) + for (w=0; w<d; w++) + 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]; + for (v=0; v<d; v++) + nij[(i*d+j)*m+(t*d+u)+d+1] += z*M[(v+1)*d*d+t*d+u]*li[k*m+v+1]; + } + } + } + } +} + +void d2x(li,lij,nij,M,m,dd,d) +double *li, *lij, *nij, *M; +int m, dd, d; +{ int i, j, k, l, z; + double t; + for (i=0; i<dd; i++) + for (j=0; j<dd; j++) + { for (k=0; k<d; k++) + { for (l=0; l<d; l++) + { t = M[i*d+k] * M[j*d+l]; + if (t != 0.0) + { for (z=0; z<m; z++) + nij[(i*d+j)*m+z] += t*lij[(k*d+l)*m+z]; + } + } + t = M[(k+1)*d*d+i*d+j]; + if (t!=0.0) + for (z=0; z<m; z++) + nij[(i*d+j)*m+z] += t*li[k*m+z]; + } + } +} + +int k0x(x,d,kap,M) +double *x, *kap, *M; +int d; +{ double det, *lij, *nij, z; + int j, m, r; + + r = 1 + ((d>=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; i<d; i++) + { t = 0; + for (j=0; j<d; j++) t += M[i*d+j]*li[j*m]; + fd[i+1] = ni[i*m] = t; + + for (j=0; j<d; j++) + { t = 0; + for (k=0; k<d; k++) + for (l=0; l<d; l++) + t += li[k*m+l+1] * M[i*d+k] * M[j*d+l]; + ni[i*m+j+1] = t; + } + } +} + +void d1x(li,ni,m,d,M) +double *li, *ni, *M; +int m, d; +{ int i, j, k; + memcpy(fd,ft,m*sizeof(double)); + setzero(ni,m*d); + for (j=0; j<d; j++) + for (k=0; k<d; k++) + if (M[j*d+k]!=0) + for (i=0; i<m; i++) ni[j*m+i] += M[j*d+k]*li[k*m+i]; +} + +int l1x(x,d,lap,M) +double *x, *lap, *M; +int d; +{ double det, sumcj, *u, v[TUBE_MXDIM]; + double *ll, *li, *lij, *ni, *nij; + int i, j, m; + if (kap_terms<=1) return(0); + m = globm; + li = &ft[m]; lij = &ft[(d+1)*m]; + ni = &fd[m]; nij = &fd[(d+1)*m]; + setzero(ni,m*d); + setzero(nij,m*d*d); + + if (use_covar) d1c(li,ni,m,d,M); + else d1x(li,ni,m,d,M); + +/* the last (d+1) columns of nij are free, use for an extra copy of ni */ + ll = &fd[d*d*m]; + u = &ll[d*m]; + if (use_covar) + memcpy(u,&ni[(d-1)*m],d*sizeof(double)); /* cov(ld, (l,l1,...ld-1)) */ + else + memcpy(ll,fd,(d+1)*m*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[(m+1)*j]/fd[0]; + lap[0] = det; + if ((kap_terms==2) | (d<=1)) return(1); + + sumcj = 0.0; + if (use_covar) + { d2c(ft,fd,li,ni,lij,nij,M,m,d-1,d); + chol_solve(fd,u,m,d); + for (i=0; i<d-1; i++) + { v[0] = 0; + for (j=0; j<d-1; j++) + v[j+1] = nij[(i*d+j)*m+d] - innerprod(u,&nij[(i*d+j)*m],d); + chol_solve(fd,v,m,d); + sumcj -= v[i+1]; + } + } + else + { d2x(li,lij,nij,M,m,d-1,d); + rproject(u,ll,fd,m,d); + for (i=0; i<d-1; i++) + { v[0] = 0; + for (j=0; j<d-1; j++) v[j+1] = innerprod(&nij[(i*d+j)*m],u,m); + qrsolv(fd,v,m,d); + sumcj -= v[i+1]; + } + } + + lap[1] = sumcj*det*fd[0]/fd[(m+1)*d]; + if ((kap_terms==3) | (d==2)) return(2); + + if (use_covar) lap[2] = k2c(nij,ll,m,d-1,d)*det; + else lap[2] = k2x(nij,ll,m,d-1,d)*det; + return(3); +} + +int m0x(x,d,m0,M) +double *x, *m0, *M; +int d; +{ double det, *li, *ni, *lij, *nij, *ll, *u1, *u2; + double om, so, co, sumcj, v[TUBE_MXDIM]; + int m, i, j; + + if ((kap_terms<=2) | (d<=1)) return(0); + + m = globm; + li = &ft[m]; lij = &ft[(d+1)*m]; + ni = &fd[m]; nij = &fd[(d+1)*m]; + setzero(ni,m*d); + setzero(nij,m*d*d); + + if (use_covar) d1c(li,ni,m,d,M); + else d1x(li,ni,m,d,M); + +/* the last (d+1) columns of nij are free, use for an extra copy of ni */ + ll = &fd[d*d*m]; + u1 = &ll[d*m]; + u2 = &ll[(d-1)*m]; + if (use_covar) + { memcpy(u1,&ni[(d-1)*m],d*sizeof(double)); + memcpy(u2,&ni[(d-2)*m],d*sizeof(double)); + } + else + memcpy(ll,fd,(d+1)*m*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-1; j++) + det *= fd[j*(m+1)]/fd[0]; + om = atan2(fd[d*(m+1)],-fd[d*(m+1)-1]); + m0[0] = det*om; + if ((kap_terms==3) | (d==2)) return(1); + + so = sin(om)/fd[d*(m+1)]; + co = (1-cos(om))/fd[(d-1)*(m+1)]; + sumcj = 0.0; + if (use_covar) + { d2c(ft,fd,li,ni,lij,nij,M,m,d-2,d); + chol_solve(fd,u1,m,d); + chol_solve(fd,u2,m,d-1); + for (i=0; i<d-2; i++) + { v[0] = 0; + for (j=0; j<d-2; j++) + v[j+1] = + so*(nij[(i*d+j)*m+d]-innerprod(u1,&nij[(i*d+j)*m],d)) + +co*(nij[(i*d+j)*m+d-1]-innerprod(u2,&nij[(i*d+j)*m],d-1)); + qrsolv(fd,v,m,d-1); + sumcj -= v[i+1]; + } + } + else + { d2x(li,lij,nij,M,m,d-2,d); + rproject(u1,ll,fd,m,d); + rproject(u2,ll,fd,m,d-1); /* now, u1, u2 are unnormalized n1*, n2* */ + for (i=0; i<m; i++) + u1[i] = so*u1[i] + co*u2[i]; /* for n1*, n2* */ + for (i=0; i<d-2; i++) + { v[0] = 0; + for (j=0; j<d-2; j++) + v[j+1] = innerprod(&nij[(i*d+j)*m],u1,m); + qrsolv(fd,v,m,d-1); + sumcj -= v[i+1]; + } + } + + m0[1] = sumcj*det*fd[0]; + return(2); +} + +int n0x(x,d,n0,M) +double *x, *n0, *M; +int d; +{ double det, *li, *ni, *a0, *a1, *a2; + int j, m; + + if ((kap_terms <= 3) | (d <= 2)) return(0); + + m = globm; + li = &ft[m]; + ni = &fd[m]; + + if (use_covar) d1c(li,ni,m,d,M); + else d1x(li,ni,m,d,M); + + det = 1; + if (use_covar) chol_dec(fd,m,d+1); + else qr(fd,m,d+1,NULL); + for (j=1; j<d-2; j++) + det *= fd[j*(m+1)]/fd[0]; + + a0 = &ni[(d-3)*m+d-2]; + a1 = &ni[(d-2)*m+d-2]; + a2 = &ni[(d-1)*m+d-2]; + + a0[0] = a1[1]*a2[2]; + a0[1] =-a1[0]*a2[2]; + a0[2] = a1[0]*a2[1]-a1[1]*a2[0]; + a1[0] = 0; + a1[1] = a2[2]; + a1[2] =-a2[1]; + a2[0] = a2[1] = 0.0; a2[2] = 1.0; + rn3(a0); rn3(a1); + n0[0] = det*sptarea(a0,a1,a2); + return(1); +} + +int kodf(ll,ur,mg,kap,lap) +double *ll, *ur, *kap, *lap; +int *mg; +{ double x[1], *l0, *l1, t, sum; + int i, j, n; + + sum = 0.0; + for (i=0; i<=mg[0]; i++) + { if (i&1) { l1 = fd; l0 = ft; } + else { l1 = ft; l0 = fd; } + x[0] = ll[0] + (ur[0]-ll[0])*i/mg[0]; + n = wdf(x,l0,0); + + t = sqrt(innerprod(l0,l0,n)); + for (j=0; j<n; j++) l0[j] /= t; + + if (i>0) + { t = 0.0; + for (j=0; j<n; j++) t += (l1[j]-l0[j])*(l1[j]-l0[j]); + sum += 2*asin(sqrt(t)/2); + } + } + kap[0] = sum; + if (kap_terms<=1) return(1); + kap[1] = 0.0; + lap[0] = 2.0; + return(2); +} + +int tube_constants(f,d,m,ev,mg,fl,kap,wk,terms,uc) +double *fl, *kap, *wk; +int d, m, ev, *mg, (*f)(), terms, uc; +{ int aw, deb=0; + double k0[4], l0[3], m0[2], n0[1], z[TUBE_MXDIM]; + + wdf = f; + + aw = (wk==NULL); + if (aw) { + wk = (double *)calloc(k0_reqd(d,m,uc),sizeof(double)); + if ( wk == NULL ) { + printf("Problem allocating memory for wk\n");fflush(stdout); + } + } + assignk0(wk,d,m); + + k0[0] = k0[1] = k0[2] = k0[3] = 0.0; + l0[0] = l0[1] = l0[2] = 0.0; + m0[0] = m0[1] = 0.0; + n0[0] = 0.0; + + use_covar = uc; + kap_terms = terms; + if ((kap_terms <=0) | (kap_terms >= 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 <math.h> +#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; i<m; i++) if (k0[i] != 0.0) + p += k0[i] * ibeta(1-c*c,(n-d+i-1)/2.0,(d+1-i)/2.0) / area(d+1-i); + return( (s==TWO_SIDED) ? 2*p : p ); +} + +double tailp_gaussian(c,k0,m,d,s,n) +double c, *k0, n; +int m, d, s; +{ int i; + double p; + p = 0.0; + for (i=0; i<m; i++) if (k0[i] != 0.0) + p += k0[i] * (1-pchisq(c*c,(double) d+1-i)) / area(d+1-i); + return( (s==TWO_SIDED) ? 2*p : p ); +} + +double tailp_tprocess(c,k0,m,d,s,n) +double c, *k0, n; +int m, d, s; +{ int i; + double p; + p = 0.0; + for (i=0; i<m; i++) if (k0[i] != 0.0) + p += k0[i] * (1-pf(c*c/(d+1-i),(double) d+1-i, n)) / area(d+1-i); + return( (s==TWO_SIDED) ? 2*p : p ); +} + +double taild_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; i<m; i++) if (k0[i] != 0.0) + 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); + return( (s==TWO_SIDED) ? 2*p : p ); +} + +double taild_gaussian(c,k0,m,d,s,n) +double c, *k0, n; +int m, d, s; +{ int i; + double p; + p = 0.0; + for (i=0; i<m; i++) if (k0[i] != 0.0) + p += k0[i] * 2*c*dchisq(c*c,(double) d+1-i,0) / area(d+1-i); + return( (s==TWO_SIDED) ? 2*p : p ); +} + +double taild_tprocess(c,k0,m,d,s,n) +double c, *k0, n; +int m, d, s; +{ int i; + double p; + p = 0.0; + for (i=0; i<m; i++) if (k0[i] != 0.0) + p += k0[i] * 2*c*df(c*c/(d+1-i),(double) d+1-i, n,0) / ((d+1-i)*area(d+1-i)); + return( (s==TWO_SIDED) ? 2*p : p ); +} + +double tailp(c,k0,m,d,s,nu, process) +double c, *k0, nu; +int m, d, s, process; +{ switch(process) + { case UNIF: return(tailp_uniform(c,k0,m,d,s,nu)); + case GAUSS: return(tailp_gaussian(c,k0,m,d,s,nu)); + case TPROC: return(tailp_tprocess(c,k0,m,d,s,nu)); + } + mut_printf("taild: unknown process.\n"); + return(0.0); +} + +double taild(c,k0,m,d,s,nu, process) +double c, *k0, nu; +int m, d, s, process; +{ switch(process) + { case UNIF: return(taild_uniform(c,k0,m,d,s,nu)); + case GAUSS: return(taild_gaussian(c,k0,m,d,s,nu)); + case TPROC: return(taild_tprocess(c,k0,m,d,s,nu)); + } + mut_printf("taild: unknown process.\n"); + return(0.0); +} + +double critval(alpha,k0,m,d,s,nu,process) +double alpha, *k0, nu; +int m, d, s, process; +{ double c, cn, c0, c1, tp, td; + int j, maxit; + double (*tpf)(), (*tdf)(); + + maxit = 20; + if (m<0) + { mut_printf("critval: no terms?\n"); + return(2.0); + } + if (m>d+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; j<maxit; j++) + { tp = tpf(c,k0,m,d,s,nu)-alpha; + td = tdf(c,k0,m,d,s,nu); + if (tp>0) c0 = c; + if (tp<0) c1 = c; + cn = c + tp/td; + if (cn<c0) cn = (c+c0)/2; + if ((c1>0.0) && (cn>c1)) cn = (c+c1)/2; + c = cn; + if (fabs(tp/alpha)<1.0e-10) return(c); + } + return(c); +}