home *** CD-ROM | disk | FTP | other *** search
- #include "all.h"
- #include "regtabext.h"
-
- LoadSg3() /*force load of segment*/
- {
- ;
- }
-
- Spline( X,Y, N, C, X0,Y0, F, AM,BM,CM,DM,EM,FM, LAST ) /* natural cubic splines */
- float X[], Y[], C[], X0, *Y0, AM[], BM[], CM[], DM[], EM[], FM[];
- int N, F, *LAST;
-
- /* X THE ARRAY OF X VALUES ARRANGED IN ORDER OF INCREASING X VALUE WITH NO DUPLICATIONS
- Y THE ARRAY OF Y VALUES
- N THE NUMBER OF (X,Y) PAIRS
- C AN ARRAY INTO WHICH THE SPLINE COEFFICIENTS ARE STORED
- X0 AN ARBITRARY X VALUE AT WHICH THE SPLINE IS TO BE EVALUATED
- Y0 POINTER TO RETURN THE VALUE OF Y AT X0
- F A FLAG, COMPUTE COEFFICIENTS ON TRUE, EVALUATE SPLINE AT X0 ON FALSE
- AM TEMP ARRAY OF LENGTH N+2
- BM TEMP ARRAY OF LENGTH N+2
- CM TEMP ARRAY OF LENGTH N+2
- DM TEMP ARRAY OF LENGTH N+2
- EM TEMP ARRAY OF LENGTH N+2
- FM TEMP ARRAY OF LENGTH N+2
- LAST POINTER TO INTEGER FOR TEMPORARY STORAGE */
- {
- int I, J, JP1;
- float HJ;
- char s[80];
-
- if (F) { /* compute spline coefficients */
- *LAST=1;
- for (I=2; I<=(N-1); I++ ) {
- X0 = (Y[I+1]-Y[I])/(X[I+1]-X[I]);
- X0 = X0 - (Y[I]-Y[I-1])/(X[I]-X[I-1]);
- DM[I-1] = 6.0*X0;
- BM[I-1] = 2.0*(X[I+1]-X[I-1]);
- AM[I-1] = X[I+1] - X[I];
- }
-
- TRIDI(AM,BM,CM,DM,C,N-2,EM,FM);
-
- C[N]=0.0; /* SHIFT ALL THE C'S AND SET C(1)=C(N)=0.0 */
- for( I=2; I<=(N-1); I++ ) {
- J = N-I;
- C[J+1]=C[J];
- }
- C[1] = 0.0;
-
- } /*end if compute spline coefficients*/
-
-
- else { /* evaluate spline at X0 */
-
- /* locate proper knot */
- if( (X0<=X[(*LAST)+1]) && (X0>=X[*LAST]) ) { /*check current knot*/
- J = *LAST;
- JP1 = J+1;
- } /*end if*/
- else { /*check elsewhere*/
- (*LAST)++;
- if ( (*LAST)>(N+1) ) *LAST=N+1;
- if ( (X0<=X[(*LAST)+1]) && (X0>=X[*LAST]) ) { /*check next knot*/
- J = *LAST;
- JP1 = J+1;
- }
- else if (X0<X[1]) { /*check off beginning*/
- J = 1;
- JP1 = 2;
- }
- else if (X0>X[N]) { /*check off end*/
- J = N-1;
- JP1 = N;
- }
- else { /*scan all knots*/
- for( I=1; I<=(N-1); I++ ) {
- if( (X0<=X[I+1]) && (X0>=X[I]) ) {
- J=I;
- JP1=I+1;
- break;
- } /*end if in interval*/
- } /*end for*/
- } /*end else*/
- } /*end if*/
- *LAST = J;
-
- /* COMPUTE Y0 AT X0 */
- HJ = X[JP1] - X[J];
- *Y0 = (C[J]/(6.0*HJ)) * (X[JP1]-X0)*(X[JP1]-X0)*(X[JP1]-X0);
- *Y0 += (C[JP1]/(6.0*HJ)) * (X0-X[J])*(X0-X[J])*(X0-X[J]);
- *Y0 += (Y[JP1]/HJ-C[JP1]*HJ/6.0) * (X0-X[J]);
- *Y0 += (Y[J]/HJ-C[J]*HJ/6.0) * (X[JP1]-X0);
- } /*end if evaluate spline*/
- }
-
- SplInterpolate()
- {
- float *xd, *yd, *c, *am, *bm, *cm, *dm, *em, *fm; /*temporary arrays*/
- float firstX, lastX, x0, y0;
- int npair, col, i, j, k, newRows, oldRows, last, goodX;
- long bytesNeeded;
- char str[cmdWordLen];
-
- if( table.header.interpolated ) {
- ErrMsg("table already interpolated");
- }
- if( table.header.rows < 4 ) {
- ErrMsg("not enough rows");
- }
- if( table.header.cols < 2 ) {
- ErrMsg("not enough cols");
- }
-
- SToR( command.cmdWord[1], &(table.header.samp), FALSE );
- if (table.header.samp<=0) {
- table.header.samp = 1.0;
- ErrMsg("samp must be > 0");
- }
-
- /* find first non-NaN x value */
- j=FALSE;
- for( i=1; i<=table.header.rows; i++ ) {
- GetTable( i, 1, &firstX );
- if( !NaN(&firstX) ) {
- j=TRUE;
- k=i;
- break;
- } /*end if*/
- } /*end for*/
- if( (!j) || (k==table.header.rows) ) ErrMsg("not enough data in col 1");
-
- /* find last non-NaN x value */
- for( i=table.header.rows; i>=1; i-- ) {
- GetTable( i, 1, &lastX );
- if( !NaN(&lastX) ) {
- break;
- } /*end if*/
- } /*end for*/
-
- /* count up non-NaN x values */
- goodX=0;
- for( i=1; i<=table.header.rows; i++ ) {
- GetTable( i, 1, &x0 );
- if( !NaN(&x0) ) {
- goodX++;
- } /*end if*/
- } /*end for*/
- if( goodX<4 ) ErrMsg("not enough data in col 1");
-
- /* check for points that are out of order */
- x0 = firstX;
- for( i=k+1; i<=table.header.rows; i++ ) {
- GetTable( i, 1, &y0 );
- if( !NaN(&y0) ) {
- if( y0<=x0 ) ErrMsg("data in col 1 out of order");
- x0 = y0;
- } /*end if*/
- } /*end for*/
-
- bytesNeeded = 4L * (4+goodX);
- if( (xd=NewPtr(bytesNeeded)) == 0L ) {
- ErrMsg("not enough free memory");
- }
- if( (yd=NewPtr(bytesNeeded)) == 0L ) {
- DisposPtr(xd);
- ErrMsg("not enough free memory");
- }
- if( (c=NewPtr(bytesNeeded)) == 0L ) {
- DisposPtr(xd);
- DisposPtr(yd);
- ErrMsg("not enough free memory");
- }
- if( (am=NewPtr(bytesNeeded)) == 0L ) {
- DisposPtr(xd);
- DisposPtr(yd);
- DisposPtr(c);
- ErrMsg("not enough free memory");
- }
- if( (bm=NewPtr(bytesNeeded)) == 0L ) {
- DisposPtr(xd);
- DisposPtr(yd);
- DisposPtr(c);
- DisposPtr(am);
- ErrMsg("not enough free memory");
- }
- cm = am-1;
- if( (dm=NewPtr(bytesNeeded)) == 0L ) {
- DisposPtr(xd);
- DisposPtr(yd);
- DisposPtr(c);
- DisposPtr(am);
- DisposPtr(bm);
- ErrMsg("not enough free memory");
- }
- if( (em=NewPtr(bytesNeeded)) == 0L ) {
- DisposPtr(xd);
- DisposPtr(yd);
- DisposPtr(c);
- DisposPtr(am);
- DisposPtr(bm);
- DisposPtr(dm);
- ErrMsg("not enough free memory");
- }
- if( (fm=NewPtr(bytesNeeded)) == 0L ) {
- DisposPtr(xd);
- DisposPtr(yd);
- DisposPtr(c);
- DisposPtr(am);
- DisposPtr(bm);
- DisposPtr(dm);
- DisposPtr(em);
- ErrMsg("not enough free memory");
- }
-
- table.header.start = firstX;
- x0 = 1.0 + ((lastX-firstX)/table.header.samp);
- oldRows = table.header.rows;
- if ( ((long)x0) > ((long)table.header.maxRows) ) {
- WriteLine("warning. some data lost from end of columns");
- newRows = table.header.maxRows;
- } /*end if*/
- else {
- newRows= (int)x0;
- } /*end if*/
-
- for (col=2; col<=table.header.cols; col++ ) {
-
- /* stuff arrays xd and yd with non-Nan data */
- i=1;
- npair=0;
- while( NextNotNan( i, 1, col, &i ) ) {
- npair++;
- GetTable( i, 1, (xd+npair) );
- GetTable( i, col, (yd+npair) );
- i++;
- } /*end while*/
-
- if (npair<4) {
- IToS( col, str );
- WritePhrase("warning: not enough data in col ");
- WriteLine(str);
- table.header.rows = newRows;
- for( j=1; j<=table.header.rows; j++ ) {
- SetTable(j,col,infinity,FALSE);
- }
- table.header.rows=oldRows;
- } /*end if pairs<4*/
- else { /*npair>=4*/
- Spline( xd,yd, npair, c, x0,&y0, TRUE, am,bm,cm,dm,em,fm, &last );
- for( i=1; i<=newRows; i++ ) {
- x0 = table.header.start + table.header.samp*((float)(i-1));
- Spline( xd,yd, npair, c, x0,&y0, FALSE, am,bm,cm,dm,em,fm, &last );
- table.header.rows = newRows;
- SetTable( i, col, y0, FALSE );
- table.header.rows = oldRows;
- } /*end for i*/
- } /*end if pairs>=4*/
- } /*end for col*/
-
- table.header.interpolated=TRUE;
- table.header.rows = newRows;
- Header2Vars();
- CreateCol1();
- DisposPtr(xd);
- DisposPtr(yd);
- DisposPtr(c);
- DisposPtr(am);
- DisposPtr(bm);
- DisposPtr(dm);
- DisposPtr(em);
- DisposPtr(fm);
- }
-
-
-
- TRIDI( A,B,C, D, T, N, E,F ) /* solves tri-diagonal matrix equation */
- float A[], B[], C[], D[], T[], E[], F[];
- int N;
-
- /*THE MATRIX EQUATION SOLVED IS :
-
- ( B1 A1 0 0 0 0 . ) ( T1 ) ( D1 )
- ( ) ( ) ( )
- ( C2 B2 A2 0 0 0 . ) ( T2 ) ( D2 )
- ( ) ( ) ( )
- ( 0 C3 B3 A3 0 0 . ) ( T3 ) = ( D3 )
- ( ) ( ) ( )
- ( 0 0 C4 B4 A4 0 . ) ( T4 ) ( D4 )
- ( ) ( ) ( )
- ( . . . . . . . ) ( . ) ( . )
- ( ) ( ) ( )
- ( 0 0 0 0 0 CN BN ) ( TN ) ( DN )
-
- E, F are temp arrays of length N+2 */
-
- {
- int I, J;
- float TEMP;
-
- E[1] = -A[1]/B[1];
- F[1] = D[1]/B[1];
- for( I=2; I<=(N-1); I++ ) {
- TEMP = B[I] + C[I] * E[I-1];
- E[I] = - A[I] / TEMP;
- F[I] = ( D[I] - C[I]*F[I-1] ) / TEMP;
- } /*end for*/
-
- T[N] = (D[N]/C[N]-F[N-1]) / (E[N-1]+B[N]/C[N]);
-
- for( J=1; J<=N-1; J++ ) {
- I=N-J;
- T[I] = E[I] * T[I+1] + F[I];
- } /* end for */
- }
-
-