/* Copyright (c) 1997 Lucent Technologies */ /* All Rights Reserved */ /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF LUCENT. */ /* The copyright notice above does not evidence any */ /* actual or intended publication of such source code. */ /* sample funcadd */ #include "stdlib.h" /* for atoi */ #include "math.h" #include "funcadd.h" /* includes "stdio1.h" */ #include "myalloc.h" /* #define HUGE_VAL 1.0e+300 */ /* Sample function kth optionally prints its arguments using * a variant of stdio.h supplied by funcadd.h. */ #ifdef __cplusplus /* The #ifdef __cplusplus lines allow this to be compiled * either by an ANSI C compiler or by a C++ compiler. */ extern "C" { #endif static void showvec( real *x, int n, AmplExports *ae); static void showmat( real **A, int n, AmplExports *ae); static void showmat2( real **A, int n, AmplExports *ae); static void mx( real **A, real *x, real *y, int n); static double dotprod( double *x, double *y, int n); static int argmax( real *x, int n); real erf (real x); static real gammp (real a, real x); static void gser(real *gamser, real a, real x, real *gln); static void gcf( real *gammcf, real a, real x, real *gln); static real ginv(arglist *al) /* generalized inverse of a single argument */ { real x = al->ra[0]; x = x ? 1./x : 0.; if (al->derivs) { *al->derivs = -x*x; if (al->hes) *al->hes = -2.*x * *al->derivs; } return x; } static char * sginv(arglist *al) /* character-valued version of ginv */ { static char buf[32]; AmplExports *ae = al->AE; /* for sprintf */ real x = al->ra[0]; sprintf(buf, "x%.g", x ? 1./x : 0); return buf; } static real myhypot(arglist *al) /* myhypot(x,y) = sqrt(x*x + y*y) */ { real *d, *h, rv, x, x0, y, y0; x = x0 = al->ra[0]; y = y0 = al->ra[1]; if (x < 0.) x = -x; if (y < 0.) y = -y; rv = x; if (x < y) { rv = y; y = x; x = rv; } if (rv) { y /= x; rv = x * sqrt(1. + y*y); if (d = (real *)al->derivs) { d[0] = x0 / rv; d[1] = y0 / rv; if (h = al->hes) { h[0] = d[1]*d[1] / rv; h[1] = -d[0]*d[1] / rv; h[2] = d[0]*d[0] / rv; } } } else if (d = (real *)al->derivs) { d[0] = d[1] = 0; if (h = al->hes) h[0] = h[1] = h[2] = 0; } return rv; } static real ncall(void) /* returns it's invocation count */ { static real x; return ++x; } static real mean(register arglist *al) /* mean of arbitrarily many arguments */ { real x, z; real *d, *de, *ra; int *at, i, j, n, nreal; char *se, *sym; AmplExports *ae = al->AE; n = al->n; if (n <= 0) return 0; at = al->at; ra = al->ra; d = (real *)al->derivs; x = 0.0; nreal = 0; for(i=0; i= 0) { x += ra[j]; ++nreal; } else { x += z = strtod(sym = al->sa[-(j+1)], &se); if (*se) { fprintf(Stderr, "mean treating arg %d = \"%s\" as %.g\n", i+1, sym, z); fflush(Stderr); } } } if (d) { z = 1.0/n; for (i=0; iAE; static real **A=NULL, **E=NULL; static real *lambda=NULL, *x=NULL, *y=NULL, *y0=NULL; /* srand48(0); */ narg = al->n; if (narg <= 0) return 0; n = (int)(sqrt(1+8*narg)-1)/2; if (n*(n+1)/2 != narg) { fprintf(Stderr, "should be mineig({i in 1..n, j in 1..n: j>=i} A[i,j])\n"); fflush(Stderr); } at = al->at; ra = al->ra; d = (real *)al->derivs; h = al->hes; /* if (A == NULL) { CALLOC( A, n, real * ); } else { REALLOC( A, n, real * ); } for (i=0; i= 0) { A[i][j] = ra[jj]; } else { A[i][j] = z = strtod(sym = al->sa[-(jj+1)], &se); if (*se) { fprintf(Stderr, "mineig treating arg %d = \"%s\" as %.g\n", i+1, sym, z); fflush(Stderr); } } k++; } } /* showmat(A,n,ae); */ for (i=0; i= 0) {shift = lambda[0]/2 + y[0];} else {shift = y[0];} */ shift = y0[0]; fprintf(Stderr, "shift = %f \n", shift); for (i=0; ira[0]; if (al->derivs) { *al->derivs = 1; if (al->hes) *al->hes = 0; } return x; } static real R_real, R_imag; static real lx, ly, lz, qx, qy, qz, zmin, zmax; static void R(arglist *al) /* inverse of 3D spectral density on a spherical shell */ { int j, n=1000; /* int j, n=20; */ real pi = 4*atan(1); real lx, ly, lz, qx, qy, qz, zmin, zmax, z; real z_perp, lq, /* component of l in direction of q */ lox, loy, loz, /* component of l orthogonal to q */ l_mag, q_mag; lx = al->ra[0]; ly = al->ra[1]; lz = al->ra[2]; qx = al->ra[3]; qy = al->ra[4]; qz = al->ra[5]; zmin = al->ra[6]; zmax = al->ra[7]; q_mag = sqrt(qx*qx + qy*qy + qz*qz); qx /= q_mag; qy /= q_mag; qz /= q_mag; R_real=0; R_imag=0; for (j=0; jderivs) { *al->derivs = 1; if (al->hes) *al->hes = 0; } */ } static real C(arglist *al) /* inverse of 3D spectral density on a spherical shell */ { if (lx != al->ra[0] || ly != al->ra[1] || lz != al->ra[2] || qx != al->ra[3] || qy != al->ra[4] || qz != al->ra[5] || zmin != al->ra[6] || zmax != al->ra[7] ) { R(al); } return R_real; } static real S(arglist *al) /* inverse of 3D spectral density on a spherical shell */ { if (lx != al->ra[0] || ly != al->ra[1] || lz != al->ra[2] || qx != al->ra[3] || qy != al->ra[4] || qz != al->ra[5] || zmin != al->ra[6] || zmax != al->ra[7] ) { R(al); } return R_imag; } static real kth_eig(register arglist *al) /* minimum kth of a symmetric matrix */ { real z, lambdak, normx, normy, shift=0, cosine, ydotEkk, lambda0=HUGE_VAL, hm, num; real *e0, *ek, *d, *h, *ra; int *at, i, ii, j, jj, k, kk, m, n, N, cnt=0, i0; char *se, *sym; AmplExports *ae = al->AE; static real **A=NULL, **E=NULL; static real *lambda=NULL, *x=NULL, *y=NULL, *y0=NULL; /* srand48(0); */ N = al->n - 1; if (N <= 0) return 0; n = (int)(sqrt(1+8*N)-1)/2; if (n*(n+1)/2 != N) { fprintf(Stderr, "should be kth_eig(k, {i in 1..n, j in 1..n: j>=i} A[i,j])\n"); fflush(Stderr); } at = al->at; ra = al->ra; d = (real *)al->derivs; h = al->hes; i0 = (int)al->ra[0]; /* if (A == NULL) { CALLOC( A, n, real * ); } else { REALLOC( A, n, real * ); } for (i=0; i= 0) { A[i][j] = ra[jj]; } else { A[i][j] = z = strtod(sym = al->sa[-(jj+1)], &se); if (*se) { fprintf(Stderr, "kth_eig treating arg %d = \"%s\" as %.g\n", i+1, sym, z); fflush(Stderr); } } k++; } } /* showmat(A,n,ae); */ for (i=0; iAE; static real **A=NULL, Ident, **A0=NULL; static int convex_flag=1; N = al->n; if (N <= 2) return 0; n = (int)al->ra[N-1]; k0 = (int)al->ra[N-2]; k0--; if (n*(n+1)/2 != N-2) { fprintf(Stderr, "should be kth_diag({i in 1..n, j in 1..n: j>=i} A[i,j],k,n)\n"); fflush(Stderr); } at = al->at; ra = al->ra; d = (real *)al->derivs; h = al->hes; /* fprintf(Stderr,"IN KTH_DIAG \n"); fprintf(Stderr,"k0 = %3d \n", k0); */ if (A == NULL) { REALLOC( A, n, real *); A[0] = NULL; } else { REALLOC( A, n, real *); } REALLOC( A[0], 2*n*n, real); for (i=0, k=0; i= 0) { A[i][j] = ra[jj]; } else { A[i][j] = z = strtod(sym = al->sa[-(jj+1)], &se); if (*se) { fprintf(Stderr, "kth_diag treating arg %d = \"%s\" as %.g\n", i+1, sym, z); fflush(Stderr); } } A[j][i] = A[i][j]; k++; } for(j=n; j<2*n; j++) { A[i][j] = 0; } A[i][n+i] = 1; } for (i=0; i 0.001) ||(i!=j && fabs(Ident) > 0.001) ) { fprintf(Stderr,"error in Gaussian elimination \n"); } } } } if (diagval < -1.0e-12) {convex_flag = 0;} if (k0 == n-1) { if (convex_flag == 0) { fprintf(Stderr,"matrix X not positive semidefinite \n"); } convex_flag = 1; } return diagval; } static real kth_diag_eps(register arglist *al) /* kth diagonal element of D in LDL^T */ /* must be called in order: 1,2,...,n */ { real z, diagval; real *d, *h, *ra; int *at, i, ii, j, jj, k, m, n, N; static int k0=-1; char *se, *sym; AmplExports *ae = al->AE; static real **A=NULL, Ident, **A0=NULL; N = al->n; if (N <= 0) return 0; n = (int)(sqrt(1+8*N)-1)/2; if (n*(n+1)/2 != N) { fprintf(Stderr, "should be kth_diag({i in 1..n, j in 1..n: j>=i} A[i,j])\n"); fflush(Stderr); } at = al->at; ra = al->ra; d = (real *)al->derivs; h = al->hes; k0++; if (k0==n) k0 = 0; /* fprintf(Stderr,"IN KTH_DIAG \n"); fprintf(Stderr,"k0 = %3d \n", k0); */ if (A == NULL) { REALLOC( A, n, real *); A[0] = NULL; } else { REALLOC( A, n, real *); } REALLOC( A[0], 2*n*n, real); for (i=0, k=0; i= 0) { A[i][j] = ra[jj]; } else { A[i][j] = z = strtod(sym = al->sa[-(jj+1)], &se); if (*se) { fprintf(Stderr, "kth_diag treating arg %d = \"%s\" as %.g\n", i+1, sym, z); fflush(Stderr); } } A[j][i] = A[i][j]; k++; } for(j=n; j<2*n; j++) { A[i][j] = 0; } A[i][n+i] = 1; A[i][i] += 1.0e-6; } for (i=0; i 0.001) ||(i!=j && fabs(Ident) > 0.001) ) { fprintf(Stderr,"error in Gaussian elimination \n"); } } } } return diagval; } static real kth_diag2(register arglist *al) /* kth diagonal element of D in LDL^T */ /* must be called in order: 1,2,...,n */ { real z, diagval; real *d, *h, *ra; int *at, i, ii, j, jj, k, m, n, N; static int k0=-1; char *se, *sym; AmplExports *ae = al->AE; static real **A=NULL, Ident, **A0=NULL; N = al->n - 1; if (N <= 0) return 0; n = (int)(sqrt(N)); if (n*n != N) { fprintf(Stderr, "should be kth_diag2(k, {i in 1..n, j in 1..n} A[i,j])\n"); fflush(Stderr); } at = al->at; ra = al->ra; d = (real *)al->derivs; h = al->hes; k = (int)al->ra[0]; k--; /* convert from 1..n to 0..n-1 */ if (k != k0+1 && k != 0) { fprintf(Stderr, "k in kth_diag2 not in increasing order \n"); fflush(Stderr); } k0 = k; if (A == NULL) { REALLOC( A, n, real *); A[0] = NULL; } else { REALLOC( A, n, real *); } REALLOC( A[0], 2*n*n, real); for (i=0, k=0; i= 0) { A[i][j] = ra[jj]; } else { A[i][j] = z = strtod(sym = al->sa[-(jj+1)], &se); if (*se) { fprintf(Stderr, "kth_diag2 treating arg %d = \"%s\" as %.g\n", i+1, sym, z); fflush(Stderr); } } k++; } for(j=n; j<2*n; j++) { A[i][j] = 0; } A[i][n+i] = 1; } for (i=0; i 0.00001) ||(i!=j && fabs(Ident) > 0.00001) ) { fprintf(Stderr,"error in Gaussian elimination \n"); } } } } return diagval; } static real myerf(arglist *al) /* 1/sqrt(2 pi) int_-infty^x e^{-t^2/2} dt */ { int j; double h = 1.0/128.0, x0 = -10; double h2 = h/2; double myerf=0; double pi = 4*atan(1); double rtp = sqrt(2*pi); double rt = sqrt(2); double deriv; real x = al->ra[0]; myerf = (erf(x/rt) + 1)/2; if (al->derivs) { deriv = exp(-x*x/2)/rtp; *al->derivs = deriv; if (al->hes) *al->hes = -x * deriv; } return myerf; } static real stderf(arglist *al) /* 2/sqrt(pi) int_0^x e^{-t^2} dt */ { int j; double h = 1.0/128.0, x0 = -10; double h2 = h/2; double stderf=0; double pi = 4*atan(1); double rp = sqrt(pi); double rt = sqrt(2); double deriv; real x = al->ra[0]; stderf = erf(x); if (al->derivs) { deriv = 2*exp(-x*x)/rp; *al->derivs = deriv; if (al->hes) *al->hes = -2*x * deriv; } return stderf; } static void showvec( real *x, int n, AmplExports *ae) { int i, j; for(i=0; i=i) { fprintf(Stderr, "%10.4f ", A[i][j]); } else { fprintf(Stderr, " "); } } fprintf(Stderr, "\n"); fflush(Stderr); } } static void showmat2( real **A, int n, AmplExports *ae) { int i, j; for(i=0; i max) {ii=i; max=fabs(x[i]);} return ii; } static real mymin(register arglist *al) /* minimum eigenvalue of a symmetric matrix */ { real z, x0=HUGE_VAL; real *d, *h, *ra; int *at, i, j, jj, k, m, n, i0; char *se, *sym; AmplExports *ae = al->AE; static real *x=NULL; n = al->n; if (n <= 0) return 0; at = al->at; ra = al->ra; d = (real *)al->derivs; h = al->hes; REALLOC( x, n, real ); for(i=0; i= 0) { x[i] = ra[jj]; } else { x[i] = z = strtod(sym = al->sa[-(jj+1)], &se); if (*se) { fprintf(Stderr, "mymin treating arg %d = \"%s\" as %.g\n", i+1, sym, z); fflush(Stderr); } } } for (k=0; kAE; static real *x=NULL; n = al->n - 1; if (n <= 0) return 0; at = al->at; ra = al->ra; d = (real *)al->derivs; h = al->hes; REALLOC( x, n+1, real ); i0 = (int)al->ra[0]; for(i=1; i<=n; i++) { jj = at[i]; if (jj >= 0) { x[i] = ra[jj]; } else { x[i] = z = strtod(sym = al->sa[-(jj+1)], &se); if (*se) { fprintf(Stderr, "nonneg treating arg %d = \"%s\" as %.g\n", i+1, sym, z); fflush(Stderr); } } } if (d) { for (i=0; iAE; k = al->at[0] ? atoi(al->sa[0]) : (int)al->ra[0]; n = al->n; if (k < 0) { fprintf(Stderr, "kth("); comma = ""; for(i = 0; i < n; i++, comma = ", ") if ((j = al->at[i]) >= 0) fprintf(Stderr, "%s%.g", comma, al->ra[j]); else fprintf(Stderr, "%s%s", comma, al->sa[-(j+1)]); fprintf(Stderr, ")\n"); fflush(Stderr); k = -k; } if (n <= 1 || k <= 0 || k >= n) return ""; if ((j = al->at[k]) >= 0) { sprintf(buf, "%.g", al->ra[j]); return buf; } return al->sa[-(j+1)]; } static real junk(register arglist *al) /* kth diagonal element of D in LDL^T */ /* must be called in order: 1,2,...,n */ { real z, diagval; real *d, *h, *ra; int *at, i, j, jj, k, m, n, N; static int k0=-1; char *se, *sym; AmplExports *ae = al->AE; static real **A=NULL; N = al->n; if (N <= 0) return 0; n = (int)(sqrt(1+8*N)-1)/2; if (n*(n+1)/2 != N) { fprintf(Stderr, "should be kth_diag({i in 1..n, j in 1..n: j>=i} A[i,j])\n"); fflush(Stderr); } at = al->at; ra = al->ra; d = (real *)al->derivs; h = al->hes; k0++; if (k0==n) k0 = 0; /* fprintf(Stderr,"IN KTH_DIAG \n"); fprintf(Stderr,"k0 = %3d \n", k0); */ if (A == NULL) { REALLOC( A, n, real *); A[0] = NULL; } else { REALLOC( A, n, real *); } REALLOC( A[0], 2*n*n, real); for (i=0, k=0; i= 0) { A[i][j] = ra[jj]; } A[j][i] = A[i][j]; k++; } for(j=n; j<2*n; j++) { A[i][j] = 0; } A[i][n+i] = 1; } /**/ showmat2(A,n,ae); /**/ } return 1; } static void alatalon(AmplExports *ae); static double **aLat=NULL; static double **aLon=NULL; static int firstpass=1; #define SS 0.5 /* degrees of lat/lon between data points */ #define leftlon (-120) #define rightlon (-62.5) #define bottomlat ( 20.5) #define toplat ( 50) /* latitude component of wind velocity in deg/hr */ static real aLatf(register arglist *al) { int i, j; int m=1+(29.5/SS), n=1+(57.5/SS); real *d, *h, rv=0, lat, lat0, lon, lon0; AmplExports *ae = al->AE; real pi = 4*atan(1); if (firstpass) { firstpass=0; alatalon(ae); } lat = lat0 = al->ra[0]; lon = lon0 = al->ra[1]; if (lat > 90) {lat = 180-lat;} if (lat < -90) {lat = -180+lat;} if (lon > 180) {lon -= 360;} if (lon < -180) {lon += 360;} i = floor((lat- bottomlat)/SS); if (i<1) {i=1;} if (i>=m-2) {i=m-3;} j = floor((lon- leftlon)/SS); if (j<1) {j=1;} if (j>=n-2) {j=n-3;} rv = (lat-(SS*(i-1)+bottomlat)) *(lon-(leftlon+SS*(j-1))) *aLat[i+1][j+1] + ((SS*(i+2)+bottomlat)-lat) *(lon-(leftlon+SS*(j-1))) *aLat[i ][j+1] + (lat-(SS*(i-1)+bottomlat)) *((leftlon+SS*(j+2))-lon) *aLat[i+1][j ] + ((SS*(i+2)+bottomlat)-lat) *((leftlon+SS*(j+2))-lon) *aLat[i ][j ] + (lat-(SS*i+bottomlat)) *((leftlon+SS*(j+1))-lon) *aLat[i+2][j-1] + ((SS*(i+1)+bottomlat)-lat) *((leftlon+SS*(j+1))-lon) *aLat[i-1][j-1] + ((SS*(i+1)+bottomlat)-lat) *(lon-(leftlon+SS*j)) *aLat[i-1][j+2] + (lat-(SS*i+bottomlat)) *(lon-(leftlon+SS*j)) *aLat[i+2][j+2] + (lat-(SS*i+bottomlat)) *((leftlon+SS*(j+2))-lon) *aLat[i+1][j-1] + ((SS*(i+1)+bottomlat)-lat) *((leftlon+SS*(j+2))-lon) *aLat[i ][j-1] + ((SS*(i+2)+bottomlat)-lat) *((leftlon+SS*(j+1))-lon) *aLat[i-1][j ] + ((SS*(i+2)+bottomlat)-lat) *(lon-(leftlon+SS*j)) *aLat[i-1][j+1] + ((SS*(i+1)+bottomlat)-lat) *(lon-(leftlon+SS*(j-1))) *aLat[i ][j+2] + (lat-(SS*i+bottomlat)) *(lon-(leftlon+SS*(j-1))) *aLat[i+1][j+2] + (lat-(SS*(i-1)+bottomlat)) *(lon-(leftlon+SS*j)) *aLat[i+2][j+1] + (lat-(SS*(i-1)+bottomlat)) *((leftlon+SS*(j+1))-lon) *aLat[i+2][j ]; rv /= 16*SS*SS; if (d = (real *)al->derivs) { d[0] = (1 ) *(lon-(leftlon+SS*(j-1))) *aLat[i+1][j+1] + ( -1) *(lon-(leftlon+SS*(j-1))) *aLat[i ][j+1] + (1 ) *((leftlon+SS*(j+2))-lon) *aLat[i+1][j ] + ( -1) *((leftlon+SS*(j+2))-lon) *aLat[i ][j ] + (1 ) *((leftlon+SS*(j+1))-lon) *aLat[i+2][j-1] + ( -1) *((leftlon+SS*(j+1))-lon) *aLat[i-1][j-1] + ( -1) *(lon-(leftlon+SS*j)) *aLat[i-1][j+2] + (1 ) *(lon-(leftlon+SS*j)) *aLat[i+2][j+2] + (1 ) *((leftlon+SS*(j+2))-lon) *aLat[i+1][j-1] + ( -1) *((leftlon+SS*(j+2))-lon) *aLat[i ][j-1] + ( -1) *((leftlon+SS*(j+1))-lon) *aLat[i-1][j ] + ( -1) *(lon-(leftlon+SS*j)) *aLat[i-1][j+1] + ( -1) *(lon-(leftlon+SS*(j-1))) *aLat[i ][j+2] + (1 ) *(lon-(leftlon+SS*(j-1))) *aLat[i+1][j+2] + (1 ) *(lon-(leftlon+SS*j)) *aLat[i+2][j+1] + (1 ) *((leftlon+SS*(j+1))-lon) *aLat[i+2][j ]; d[0] /= 16*SS*SS; d[1] = (lat-(SS*(i-1)+bottomlat)) *(1 ) *aLat[i+1][j+1] + ((SS*(i+2)+bottomlat)-lat) *(1 ) *aLat[i ][j+1] + (lat-(SS*(i-1)+bottomlat)) *( -1) *aLat[i+1][j ] + ((SS*(i+2)+bottomlat)-lat) *( -1) *aLat[i ][j ] + (lat-(SS*i+bottomlat)) *( -1) *aLat[i+2][j-1] + ((SS*(i+1)+bottomlat)-lat) *( -1) *aLat[i-1][j-1] + ((SS*(i+1)+bottomlat)-lat) *(1 ) *aLat[i-1][j+2] + (lat-(SS*i+bottomlat)) *(1 ) *aLat[i+2][j+2] + (lat-(SS*i+bottomlat)) *( -1) *aLat[i+1][j-1] + ((SS*(i+1)+bottomlat)-lat) *( -1) *aLat[i ][j-1] + ((SS*(i+2)+bottomlat)-lat) *( -1) *aLat[i-1][j ] + ((SS*(i+2)+bottomlat)-lat) *(1 ) *aLat[i-1][j+1] + ((SS*(i+1)+bottomlat)-lat) *(1 ) *aLat[i ][j+2] + (lat-(SS*i+bottomlat)) *(1 ) *aLat[i+1][j+2] + (lat-(SS*(i-1)+bottomlat)) *(1 ) *aLat[i+2][j+1] + (lat-(SS*(i-1)+bottomlat)) *( -1) *aLat[i+2][j ]; d[1] /= 16*SS*SS; if (h = al->hes) { h[0] = 0; h[1] = aLat[i+1][j+1] -aLat[i ][j+1] -aLat[i+1][j ] +aLat[i ][j ] -aLat[i+2][j-1] +aLat[i-1][j-1] -aLat[i-1][j+2] +aLat[i+2][j+2] -aLat[i+1][j-1] +aLat[i ][j-1] +aLat[i-1][j ] -aLat[i-1][j+1] -aLat[i ][j+2] +aLat[i+1][j+2] +aLat[i+2][j+1] -aLat[i+2][j ]; h[1] /= 16*SS*SS; h[2] = 0; } } return (rv); } /* longitude component of wind velocity in deg/hr */ static real aLonf(register arglist *al) { int i, j; int m=1+(29.5/SS), n=1+(57.5/SS); real *d, *h, rv=0, lat, lon; real pi = 4*atan(1); AmplExports *ae = al->AE; if (firstpass) { firstpass=0; alatalon(ae); } /* REALLOC(aLon, m, real *); for (i=0; ira[0]; lon = al->ra[1]; if (lat > 90) {lat = 180-lat;} if (lat < -90) {lat = -180+lat;} if (lon > 180) {lon -= 360;} if (lon < -180) {lon += 360;} i = floor((lat-bottomlat)/SS); if (i<1) {i=1;} if (i>=m-2) {i=m-3;} j = floor((lon-leftlon)/SS); if (j<1) {j=1;} if (j>=n-2) {j=n-3;} rv = (lat-(SS*(i-1)+bottomlat)) *(lon-(leftlon+SS*(j-1))) *aLon[i+1][j+1] + ((SS*(i+2)+bottomlat)-lat) *(lon-(leftlon+SS*(j-1))) *aLon[i ][j+1] + (lat-(SS*(i-1)+bottomlat)) *((leftlon+SS*(j+2))-lon) *aLon[i+1][j ] + ((SS*(i+2)+bottomlat)-lat) *((leftlon+SS*(j+2))-lon) *aLon[i ][j ] + (lat-(SS*i+bottomlat)) *((leftlon+SS*(j+1))-lon) *aLon[i+2][j-1] + ((SS*(i+1)+bottomlat)-lat) *((leftlon+SS*(j+1))-lon) *aLon[i-1][j-1] + ((SS*(i+1)+bottomlat)-lat) *(lon-(leftlon+SS*j)) *aLon[i-1][j+2] + (lat-(SS*i+bottomlat)) *(lon-(leftlon+SS*j)) *aLon[i+2][j+2] + (lat-(SS*i+bottomlat)) *((leftlon+SS*(j+2))-lon) *aLon[i+1][j-1] + ((SS*(i+1)+bottomlat)-lat) *((leftlon+SS*(j+2))-lon) *aLon[i ][j-1] + ((SS*(i+2)+bottomlat)-lat) *((leftlon+SS*(j+1))-lon) *aLon[i-1][j ] + ((SS*(i+2)+bottomlat)-lat) *(lon-(leftlon+SS*j)) *aLon[i-1][j+1] + ((SS*(i+1)+bottomlat)-lat) *(lon-(leftlon+SS*(j-1))) *aLon[i ][j+2] + (lat-(SS*i+bottomlat)) *(lon-(leftlon+SS*(j-1))) *aLon[i+1][j+2] + (lat-(SS*(i-1)+bottomlat)) *(lon-(leftlon+SS*j)) *aLon[i+2][j+1] + (lat-(SS*(i-1)+bottomlat)) *((leftlon+SS*(j+1))-lon) *aLon[i+2][j ]; rv /= 16*SS*SS; if (d = (real *)al->derivs) { d[0] = (1 ) *(lon-(leftlon+SS*(j-1))) *aLon[i+1][j+1] + ( -1) *(lon-(leftlon+SS*(j-1))) *aLon[i ][j+1] + (1 ) *((leftlon+SS*(j+2))-lon) *aLon[i+1][j ] + ( -1) *((leftlon+SS*(j+2))-lon) *aLon[i ][j ] + (1 ) *((leftlon+SS*(j+1))-lon) *aLon[i+2][j-1] + ( -1) *((leftlon+SS*(j+1))-lon) *aLon[i-1][j-1] + ( -1) *(lon-(leftlon+SS*j)) *aLon[i-1][j+2] + (1 ) *(lon-(leftlon+SS*j)) *aLon[i+2][j+2] + (1 ) *((leftlon+SS*(j+2))-lon) *aLon[i+1][j-1] + ( -1) *((leftlon+SS*(j+2))-lon) *aLon[i ][j-1] + ( -1) *((leftlon+SS*(j+1))-lon) *aLon[i-1][j ] + ( -1) *(lon-(leftlon+SS*j)) *aLon[i-1][j+1] + ( -1) *(lon-(leftlon+SS*(j-1))) *aLon[i ][j+2] + (1 ) *(lon-(leftlon+SS*(j-1))) *aLon[i+1][j+2] + (1 ) *(lon-(leftlon+SS*j)) *aLon[i+2][j+1] + (1 ) *((leftlon+SS*(j+1))-lon) *aLon[i+2][j ]; d[0] /= 16*SS*SS; d[1] = (lat-(SS*(i-1)+bottomlat)) *(1 ) *aLon[i+1][j+1] + ((SS*(i+2)+bottomlat)-lat) *(1 ) *aLon[i ][j+1] + (lat-(SS*(i-1)+bottomlat)) *( -1) *aLon[i+1][j ] + ((SS*(i+2)+bottomlat)-lat) *( -1) *aLon[i ][j ] + (lat-(SS*i+bottomlat)) *( -1) *aLon[i+2][j-1] + ((SS*(i+1)+bottomlat)-lat) *( -1) *aLon[i-1][j-1] + ((SS*(i+1)+bottomlat)-lat) *(1 ) *aLon[i-1][j+2] + (lat-(SS*i+bottomlat)) *(1 ) *aLon[i+2][j+2] + (lat-(SS*i+bottomlat)) *( -1) *aLon[i+1][j-1] + ((SS*(i+1)+bottomlat)-lat) *( -1) *aLon[i ][j-1] + ((SS*(i+2)+bottomlat)-lat) *( -1) *aLon[i-1][j ] + ((SS*(i+2)+bottomlat)-lat) *(1 ) *aLon[i-1][j+1] + ((SS*(i+1)+bottomlat)-lat) *(1 ) *aLon[i ][j+2] + (lat-(SS*i+bottomlat)) *(1 ) *aLon[i+1][j+2] + (lat-(SS*(i-1)+bottomlat)) *(1 ) *aLon[i+2][j+1] + (lat-(SS*(i-1)+bottomlat)) *( -1) *aLon[i+2][j ]; d[1] /= 16*SS*SS; if (h = al->hes) { h[0] = 0; h[1] = aLon[i+1][j+1] -aLon[i ][j+1] -aLon[i+1][j ] +aLon[i ][j ] -aLon[i+2][j-1] +aLon[i-1][j-1] -aLon[i-1][j+2] +aLon[i+2][j+2] -aLon[i+1][j-1] +aLon[i ][j-1] +aLon[i-1][j ] -aLon[i-1][j+1] -aLon[i ][j+2] +aLon[i+1][j+2] +aLon[i+2][j+1] -aLon[i+2][j ]; h[1] /= 16*SS*SS; h[2] = 0; } } return (rv); } void funcadd(AmplExports *ae){ /* Insert calls on addfunc here... */ /* Arg 3, called type, must satisfy 0 <= type <= 6: * type&1 == 0: 0,2,4,6 ==> force all arguments to be numeric. * type&1 == 1: 1,3,5 ==> pass both symbolic and numeric arguments. * type&6 == 0: 0,1 ==> the function is real valued. * type&6 == 2: 2,3 ==> the function is char * valued; static storage suffices: AMPL copies the return value. * type&6 == 4: 4,5 ==> the function is random (real valued). * type&6 == 6: 6 ==> random, real valued, pass nargs real args, * 0 <= nargs <= 2. * * Arg 4, called nargs, is interpretted as follows: * >= 0 ==> the function has exactly nargs arguments * <= -1 ==> the function has >= -(nargs+1) arguments. */ addfunc("ginv", (rfunc)ginv, 0, 1, 0); addfunc("sginv", (rfunc)sginv, 2, 1, 0); addfunc("hypot", (rfunc)myhypot, 0, 2, 0); addfunc("ncall", (rfunc)ncall, 0, 0, 0); addfunc("rncall", (rfunc)ncall, 4, 0, 0); /*could change 4 to 6*/ addfunc("mean0", (rfunc)mean, 0, -1, 0); addfunc("mean", (rfunc)mean, 1, -1, 0); addfunc("mineig", (rfunc)mineig, 1, -1, 0); addfunc("kth_eig", (rfunc)kth_eig, 1, -1, 0); addfunc("linear", (rfunc)linear, 1, -1, 0); addfunc("C", (rfunc)C, 0, 8, 0); addfunc("S", (rfunc)S, 0, 8, 0); addfunc("kth_diag", (rfunc)kth_diag, 1, -1, 0); addfunc("kth_diag_eps",(rfunc)kth_diag_eps,1, -1, 0); addfunc("kth_diag2",(rfunc)kth_diag2,1, -1, 0); addfunc("junk", (rfunc)junk, 1, -1, 0); addfunc("myerf", (rfunc)myerf, 0, 1, 0); addfunc("stderf", (rfunc)stderf, 0, 1, 0); addfunc("mymin", (rfunc)mymin, 1, -1, 0); addfunc("nonneg", (rfunc)nonneg, 1, -1, 0); addfunc("kth", (rfunc)kth, 3, -2, 0); addfunc("aLatf", (rfunc)aLatf, 0, 2, 0); addfunc("aLonf", (rfunc)aLonf, 0, 2, 0); } double erf (double x) { return x < 0.0 ? -gammp(0.5, x*x) : gammp(0.5, x*x); } static double gammln(double xx) { double x, tmp, ser; static double cof[6]={76.18009173, -86.50532033, 24.01409822, -1.231739516, 0.120858003e-2, -0.536382e-5}; int j; x = xx-1.0; tmp = x+5.5; tmp -= (x+0.5)*log(tmp); ser=1.0; for (j=0; j<=5;j++) { x += 1.0; ser += cof[j]/x; } return -tmp+log(2.50662827465*ser); } static double gammp (double a, double x) { double gamser, gammcf, gln; if (x < 0.0 || a <= 0.0) { /* fprintf(Stderr,"invalid arguments in gammp\n"); exit(0); */ } if (x < (a+1.0)) { gser(&gamser,a,x,&gln); return gamser; } else { gcf(&gammcf,a,x,&gln); return 1.0-gammcf; } } #define ITMAX 100 #define EPS 3.0e-7 static void gser(double *gamser, double a, double x, double *gln) { int n; double sum, del, ap; *gln=gammln(a); if (x <= 0.0) { /* if (x < 0.0) {fprintf(Stderr,"x < 0 in gser\n"); exit(0);} */ *gamser=0.0; return; } else { ap = a; del = sum = 1.0/a; for (n=1; n<= ITMAX; n++) { ap += 1.0; del *= x/ap; sum += del; if (fabs(del) < fabs(sum)*EPS) { *gamser=sum*exp(-x+a*log(x)-(*gln)); return; } } /* fprintf(Stderr,"a too large or ITMAX too small in gser\n"); exit(0); */ } } static void gcf( double *gammcf, double a, double x, double *gln) { int n; double gold=0.0,g,fac=1.0, b1=1.0; double b0=0.0, anf, ana, an, a1, a0=1.0; *gln = gammln(a); a1 = x; for (n=1; n<=ITMAX; n++) { an= (double) n; ana = an - a; a0 = (a1+a0*ana)*fac; b0 = (b1+b0*ana)*fac; anf = an*fac; a1 = x*a0+anf*a1; b1 = x*b0+anf*b1; if (a1) { fac = 1.0/a1; g = b1*fac; if (fabs((g-gold)/g) < EPS) { *gammcf = exp(-x+a*log(x)-(*gln))*g; return; } gold = g; } } /* fprintf(Stderr,"a too large or ITMAX too small in gcf\n"); exit(0); */ } /*********************************************************************/ /*** To format the wind velocity data ***/ /*** All Rights Reserved ***/ /*********************************************************************/ #define pi (4*atan(1)) #define RADIUS 4000 #define velconv (3.6/1.609344) #define gridsize 0.5 #define yy 0.75 static void alatalon(AmplExports *ae) { int ln, lt, i, j, in, LAT, LON, index; char ch[4]; char directory[80]; double lon[85][141], lat[85][141], vel[85][141], dir[85][141]; double aLonact[85][141], aLatact[85][141]; double Lonftr, Latftr; double extralat, extralon; double sdot, beta, sinbeta, cosbeta; double weight, totalweight, templon, templat, dlat, dlon; FILE *f1, *f2, *f3; /*---- reading the longitude file -----*/ /* strcpy(directory,getenv("AMPLFUNC")); printf("AMPLFUNC = %s \n", directory); strcat(directory,"/flight/lon2"); */ strcpy(directory,"lon2"); f1 = fopen(directory, "r"); if (f1==NULL) printf("can not open %s\n", directory); fflush(stdout); for (i=0; i<85; i++) { fscanf(f1,"%s %d ", &ch, &in); for (j=0; j<141; j++) { fscanf(f1, "%lf", &lon[i][j]); lon[i][j] /= 10*pi/180; /* converting into degrees */ } } /*---- reading the latitude file ------*/ /* strcpy(directory,getenv("AMPLFUNC")); strcat(directory,"/flight/lat2"); */ strcpy(directory,"lat2"); f1 = fopen(directory, "r"); if (f1==NULL) printf("can not open %s\n", directory); fflush(stdout); for (i=0; i<85; i++) { fscanf(f1,"%s %d", &ch, &in); for (j=0; j<141; j++) { fscanf(f1, "%lf", &lat[i][j]); lat[i][j] /= 100*pi/180; /* converting into degrees */ } } /*---- reading the magnitudes of the velocities ------*/ /* strcpy(directory,getenv("AMPLFUNC")); strcat(directory,"/flight/vel2"); */ strcpy(directory,"vel2"); f1 = fopen(directory, "r"); if (f1==NULL) printf("can not open %s\n", directory); fflush(stdout); for (i=0; i<85; i++) { fscanf(f1,"%s %d", &ch, &in); for (j=0; j<141; j++) fscanf(f1, "%lf", &vel[i][j]); /* velocity units: m/s */ } /*---- reading the directions of the velocities ------*/ /* strcpy(directory,getenv("AMPLFUNC")); strcat(directory,"/flight/dir2"); */ strcpy(directory,"dir2"); f1 = fopen(directory, "r"); if (f1==NULL) printf("can not open %s\n", directory); fflush(stdout); for (i=0; i<85; i++) { fscanf(f1,"%s %d", &ch, &in); for (j=0; j<141; j++) fscanf(f1, "%lf", &dir[i][j]); /* units: degrees */ } fclose(f1); /*---- calculating the latitude component of the velocities ------*/ for (i=0; i<85; i++) for (j=0; j<141; j++) aLatact[i][j] = sin((pi/180)*dir[i][j])*vel[i][j]*velconv/RADIUS; /*---- calculating the longitude component of the velocities ------*/ for (i=0; i<85; i++) for (j=0; j<141; j++) aLonact[i][j] = cos((pi/180)*dir[i][j])*vel[i][j]*velconv/(RADIUS*cos((pi/180)*lat[i][j])); /*---- allocating memory for aLat and aLon and initializing to 0 ----*/ LON = (int)((rightlon- leftlon)/gridsize) + 1; LAT = (int)((toplat- bottomlat)/gridsize) + 1; MALLOC(aLat, LAT, double *); for (lt=0; lt 0) beta = asin(sinbeta); else beta = 2*pi + asin(sinbeta); Latftr = templat +(180/pi)*yy*sdot*sin(beta)/RADIUS; Lonftr = templon +(180/pi)*yy*sdot*cos(beta)/(RADIUS*cos(templat*pi/180)); extralat = templat + (180/pi)*0.3*yy*sdot*sin(beta)/RADIUS; extralon = templon + (180/pi)*0.3*yy*sdot*cos(beta)/(RADIUS*cos(templat*pi/180)); fprintf(f1,"%0.8f %0.8f %0.8f,\n", 2.02*sin(templon*pi/180)*cos(templat*pi/180), 2.02* sin(templat*pi/180), 2.02*cos(templon*pi/180)*cos(templat*pi/180)); fprintf(f1,"%0.8f %0.8f %0.8f,\n", 2.02*sin(Lonftr*pi/180)*cos(Latftr*pi/180), 2.02*sin(Latftr*pi/180), 2.02*cos(Lonftr*pi/180)*cos(Latftr*pi/180)); fprintf(f1,"%0.8f %0.8f %0.8f,\n", 2.02*sin(extralon*pi/180)*cos(extralat*pi/180), 2.02*sin(extralat*pi/180), 2.02*cos(extralon*pi/180)*cos(extralat*pi/180)); fprintf(f2, "%d %d -1\n", index, index+1); fprintf(f2, "%d %d -1\n", index, index+2); switch ((int)(sdot*4/120)) { case 0: fprintf(f3, "5 0 \n"); break; case 1: fprintf(f3, "5 0 \n"); break; case 2: fprintf(f3, "5 0 \n"); break; case 3: fprintf(f3, "5 0 \n"); break; case 4: fprintf(f3, "5 0 \n"); break; } index +=3; } fclose(f1); fclose(f2); fclose(f3); */ } #ifdef __cplusplus } #endif