IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Sep 21, 2004, 3:30:21 PM (22 years ago)
Author:
gusciora
Message:

Added the spline generation.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/dataManip/psMinimize.c

    r1836 r1846  
    1 /** @file  psMinimize.c
     1M/** @file  psMinimize.c
    22 *  \brief basic minimization functions
    33 *  @ingroup Math
     
    99 *  @author George Gusciora, MHPCC
    1010 *
    11  *  @version $Revision: 1.41 $ $Name: not supported by cvs2svn $
    12  *  @date $Date: 2004-09-20 23:16:10 $
     11 *  @version $Revision: 1.42 $ $Name: not supported by cvs2svn $
     12 *  @date $Date: 2004-09-22 01:30:21 $
    1313 *
    1414 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    148148}
    149149
     150/*****************************************************************************
     151 
     152CalculateSecondDerivs(): Given a set of x/y vectors corresponding to a
     153tabulated function at n points, this routine calcualtes the second
     154derivatives of the interpolating cubic splines at those n points.
     155 
     156The first and second derivatives at the endpoints, undefined in the SDR, are
     157here defined to be 0.0.
     158 
     159XXX: This algorithm is very similar to that in Numerical Recipes.
     160 *****************************************************************************/
     161float *CalculateSecondDerivs(const psVector* restrict x,        ///< Ordinates (or NULL to just use the indices)
     162                             const psVector* restrict y)        ///< Coordinates
     163{
     164    int i;
     165    int k;
     166    bool mustFreeX = false;
     167    float sig;
     168    float p;
     169    int n = y->n;
     170    float *u = (float *) psAlloc(n * sizeof(float));
     171    float *derivs2 = (float *) psAlloc(n * sizeof(float));
     172    float *X = (float *) & (x->data.F32[0]);
     173    float *Y = (float *) & (y->data.F32[0]);
     174
     175    if (x == NULL) {
     176        X = (float *) psAlloc(n * sizeof(float));
     177        for(i=0;i<n;i++) {
     178            X[i] = (float) i;
     179        }
     180        mustFreeX = true;
     181    }
     182
     183    // XXX: The first and second derivatives at the endpoints, undefined in
     184    // the SDR, are here defined to be 0.0.
     185    u[0]= 0.0;
     186    u[n-1]= 0.0;
     187    derivs2[0] = 0.0;
     188    derivs2[n-1] = 0.0;
     189
     190    for (i=1;i<=(n-2);i++) {
     191        sig = (X[i] - X[i-1]) / (X[i+1] - X[i-1]);
     192        p = sig * derivs2[i-1] + 2.0;
     193        derivs2[i] = (sig - 1.0) / p;
     194        u[i] = (Y[i+1] - Y[i])/(X[i+1]-X[i]) - (Y[i]-Y[i-1])/(X[i]-X[i-1]);
     195        u[i] = (6.0 * u[i] / (X[i+1] - X[i-1]) - sig * u[i-1]) / p;
     196    }
     197
     198    for (k=(n-2);k>=0;k--) {
     199        derivs2[k] = derivs2[k] * derivs2[k+1] + u[k];
     200    }
     201
     202
     203
     204
     205
     206
     207
     208
     209
     210    /*
     211        if (mustFreeX == true) {
     212            psFree(X);
     213        }
     214    */
     215    psFree(u);
     216
     217    return(derivs2);
     218}
     219
     220
    150221/*****************************************************************************/
    151222/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
    152223/*****************************************************************************/
     224
     225
     226
     227/*****************************************************************************
     228psVectorFitSpline1D(): given a psSpline1D data structure and a set of x/y
     229vectors, this routine generates the cublic splines which satisfy those data
     230points.
     231 
     232The formula for calculating the spline polynomials is derived from Numerical
     233Recipes in C.  The basic idea is that the polynomial is
     234 (1)     y = (A * y[0]) +
     235 (2)         (B * y[1]) +
     236 (3)         ((((A*A*A)-A) * mySpline->p_psDeriv2[0]) * H^2)/6.0 +
     237 (4)         ((((B*B*B)-B) * mySpline->p_psDeriv2[1]) * H^2)/6.0
     238Where
     239 H = x[1]-x[0], A = (x[1]-x)/H, B = (x-x[0])/H
     240The bulk of the code in this routine is the expansion of the above equation
     241into a polynomial in terms of x.  This gets pretty complicated.
     242 
     243XXX: usage of yErr is not specified in IfA documentation.
     244 *****************************************************************************/
     245
     246psSpline1D *psVectorFitSpline1D(psSpline1D *mySpline,              ///< The spline which will be generated.
     247                                const psVector* restrict x,        ///< Ordinates (or NULL to just use the indices)
     248                                const psVector* restrict y,        ///< Coordinates
     249                                const psVector* restrict yErr)     ///< Errors in coordinates, or NULL
     250{
     251    int numSplines = (y->n)-1;
     252    float tmp;
     253    float H;
     254    int i;
     255
     256    if (mySpline == NULL) {
     257        //XXX psErrorMsg()
     258    }
     259    mySpline->p_psDeriv2 = CalculateSecondDerivs(x, y);
     260
     261    for (i=0;i<numSplines;i++) {
     262        H = x->data.F32[i+1] - x->data.F32[i];
     263        //
     264        // ******** Calulate 0-order term ********
     265        //
     266        // From (1)
     267        (mySpline->spline[i])->coeff[0] = y->data.F32[i] * (x->data.F32[i+1]/H);
     268        // From (2)
     269        ((mySpline->spline[i])->coeff[0])-= (y->data.F32[i+1] * x->data.F32[i]/H);
     270        // From (3)
     271        tmp = (x->data.F32[i+1] * x->data.F32[i+1] * x->data.F32[i+1]) / (H * H * H);
     272        tmp-= (x->data.F32[i+1] / H);
     273        tmp*= (mySpline->p_psDeriv2)[i] * H * H / 6.0;
     274        ((mySpline->spline[i])->coeff[0])+= tmp;
     275        // From (4)
     276        tmp = -(x->data.F32[i] * x->data.F32[i] * x->data.F32[i]) / (H * H * H);
     277        tmp+= (x->data.F32[i] / H);
     278        tmp*= (mySpline->p_psDeriv2)[i+1] * H * H / 6.0;
     279        ((mySpline->spline[i])->coeff[0])+= tmp;
     280
     281        //
     282        // ******** Calulate 1-order term ********
     283        //
     284        // From (1)
     285        (mySpline->spline[i])->coeff[1] = - ((mySpline->p_psDeriv2)[i]) / H;
     286        // From (2)
     287        (mySpline->spline[i])->coeff[1]-= ((mySpline->p_psDeriv2)[i+1]) / H;
     288        // From (3)
     289        tmp = - (x->data.F32[i+1] * x->data.F32[i+1]) / (H * H * H);
     290        tmp+= (1.0 / H);
     291        tmp*= ((mySpline->p_psDeriv2)[i]) * H * H / 6.0;
     292        (mySpline->spline[i])->coeff[1]+= tmp;
     293        // From (4)
     294        tmp = (x->data.F32[i] + x->data.F32[i]) / (H * H * H);
     295        tmp-= (1.0 / H);
     296        tmp*= ((mySpline->p_psDeriv2)[i+1]) * H * H / 6.0;
     297        (mySpline->spline[i])->coeff[1]+= tmp;
     298
     299        //
     300        // ******** Calulate 2-order term ********
     301        //
     302        // From (3)
     303        (mySpline->spline[i])->coeff[2] = ((mySpline->p_psDeriv2)[i]) * 3.0 * x->data.F32[i+1] / 6.0;
     304        // From (4)
     305        (mySpline->spline[i])->coeff[2]-= ((mySpline->p_psDeriv2)[i+1]) * 3.0 * x->data.F32[i] / 6.0;
     306
     307        //
     308        // ******** Calulate 3-order term ********
     309        //
     310        // From (3)
     311        (mySpline->spline[i])->coeff[2] = -((mySpline->p_psDeriv2)[i]) / (6.0 * H);
     312        // From (4)
     313        (mySpline->spline[i])->coeff[2]+=  ((mySpline->p_psDeriv2)[i+1]) / (6.0 * H);
     314    }
     315
     316
     317
     318
     319
     320
     321
     322
     323
     324    return(mySpline);
     325}
    153326
    154327/******************************************************************************
     
    388561
    389562
     563
     564
     565
     566
     567
     568
     569
     570
     571
     572
     573
    390574/******************************************************************************
    391575psVectorFitPolynomial1D():  This routine must fit a polynomial of degree
     
    504688    return(min);
    505689}
     690
    506691
    507692#define STEP_SIZE 0.10
     
    551736        }
    552737    }
     738
    553739    if (null == 0) {
    554740        psTrace(".psLib.dataManip.p_psDetermineBracket", 2,
     
    685871    return(NULL);
    686872}
     873
     874
     875
     876
     877
     878
     879
     880
     881
     882
    687883
    688884
     
    8651061    return(0.0);
    8661062}
     1063
     1064
     1065
     1066
     1067
     1068
     1069
     1070
     1071
     1072
     1073
     1074
     1075
    8671076
    8681077
Note: See TracChangeset for help on using the changeset viewer.