IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jan 23, 2023, 7:10:15 AM (3 years ago)
Author:
eugene
Message:

workin on spline implementation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/psLib.20230123/src/math/psSpline.c

    r23486 r42319  
    11/** @file psSpline.c
    2 *
    3 *  @brief Contains basic spline allocation, deallocation, fitting,
    4 *         and evaluation routines.
    5 *
    6 *  This file contains the routines that allocate, free, and evaluate splines.
    7 *
    8 *  @version $Revision: 1.158 $ $Name: not supported by cvs2svn $
    9 *  @date $Date: 2007-03-14 02:36:28 $
    10 *
    11 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     2    re-written by EAM 2023.01.23
    123*/
    134
     
    167#endif
    178
    18 /*****************************************************************************/
    19 /*  INCLUDE FILES                                                            */
    20 /*****************************************************************************/
    219#include <stdio.h>
    2210#include <stdbool.h>
     
    3624#include "psMathUtils.h"
    3725
    38 /*****************************************************************************/
    39 /* DEFINE STATEMENTS                                                         */
    40 /*****************************************************************************/
    41 
    42 /*****************************************************************************/
    43 /* TYPE DEFINITIONS                                                          */
    44 /*****************************************************************************/
    45 
    46 /*****************************************************************************/
    47 /* GLOBAL VARIABLES                                                          */
    48 /*****************************************************************************/
    49 
    50 /*****************************************************************************/
    51 /* FILE STATIC VARIABLES                                                     */
    52 /*****************************************************************************/
    53 
    54 /*****************************************************************************/
    55 /* FUNCTION IMPLEMENTATION - LOCAL                                           */
    56 /*****************************************************************************/
    57 
    58 static void spline1DFree(psSpline1D *tmpSpline)
    59 {
    60     if (tmpSpline == NULL) {
    61         return;
    62     }
     26static void psSpline1DFree(psSpline1D *tmpSpline)
     27{
     28    if (tmpSpline == NULL) return;
    6329
    6430    if (tmpSpline->spline != NULL) {
     
    7844}
    7945
    80 
    81 static void PS_POLY1D_PRINT(
    82     psPolynomial1D *poly)
    83 {
    84     printf("-------------- PS_POLY1D_PRINT() --------------\n");
    85     printf("poly->nX is %d\n", poly->nX);
    86     for (psS32 i = 0 ; i < (1 + poly->nX) ; i++) {
    87         printf("poly->coeff[%d] is %f\n", i, poly->coeff[i]);
    88     }
    89 }
    90 
    9146static void PS_PRINT_SPLINE2(psSpline1D *mySpline)
    9247{
     
    9449    printf("mySpline->n is %d\n", mySpline->n);
    9550    for (psS32 i = 0 ; i < mySpline->n ; i++) {
    96         PS_POLY1D_PRINT(mySpline->spline[i]);
    97     }
    98     PS_VECTOR_PRINT_F32(mySpline->knots);
     51        // print the knots
     52    }
    9953}
    10054
    10155/*****************************************************************************
    102 CalculateSecondDerivs(): Given a set of x/y vectors corresponding to a
    103 tabulated function at n points, this routine calculates the second
    104 derivatives of the interpolating cubic splines at those n points.
    105 
    106 The first and second derivatives at the endpoints were previously undefined in
    107 the SDR.  From bugzilla #???, they are required to be 0.0, implementing natural
    108 splines.
    109 
    110 Endpoints are defined by
    111     PS_LEFT_SPLINE_DERIV
    112     PS_RIGHT_SPLINE_DERIV
    113 
    114 This routine assumes that vectors x and y are of the appropriate types/sizes
    115 (F32).
    116 
    117 XXX: use recycled vectors for internal data.
    118 XXX: do an F64 version?
     56CalculateSecondDerivs(): Given a set of x,y vectors corresponding to the spline knots, this
     57routine calculates the second derivatives of the interpolating cubic splines at those n points.
     58
     59The boundary conditions may be:
     60* first derivative specified OR
     61* second derivatives = 0
     62
     63One or the other condition may be true for each of the upper and lower bounds
     64
     65NOTE: vectors must be F32
     66
    11967 *****************************************************************************/
    120 #define PS_LEFT_SPLINE_DERIV 0.0
    121 #define PS_RIGHT_SPLINE_DERIV 0.0
     68
    12269static psF32 *calculateSecondDerivs(
    123     const psVector* x,                  ///< Ordinates
    124     const psVector* y)                  ///< Coordinates
     70    const psVector* x, ///< Ordinates
     71    const psVector* y, ///< Coordinates
     72    psF32 dyLower; // if not NAN, lower-bound 1st derivative is defined
     73    psF32 dyUpper; // if not NAN, lower-bound 1st derivative is defined
     74    )                 
    12575{
    12676    psTrace("psLib.math", 4, "---- %s() begin ----\n", __func__);
     
    190140
    191141/*****************************************************************************
    192 psVectorFitSpline1D(): given a set of x/y vectors, this routine generates the
     142psSpline1DFitVector(): given a set of x/y vectors, this routine generates the
    193143linear or cublic splines which satisfy those data points.
    194144
     
    209159XXX: What types must be supported?
    210160 *****************************************************************************/
    211 psSpline1D *psVectorFitSpline1D(
     161psSpline1D *psSpline1DFitVector(
    212162    const psVector* x,                  ///< Ordinates.
    213163    const psVector* y)                  ///< Coordinates.
     
    361311psF64?
    362312 *****************************************************************************/
    363 float psSpline1DEval(
    364     const psSpline1D *spline,
     313float psSpline1DEval_Old(
     314    const psSpline1D_Old *spline,
    365315    float x)
    366316{
     
    397347}
    398348
     349// XXX EAM : changing implementation to use yKnot, d2yKnot instead of polynomials
     350float psSpline1DEval_New(
     351    const psSpline1D *spline,
     352    float x)
     353{
     354    psTrace("psLib.math", 3, "---- %s() begin ----\n", __func__);
     355    PS_ASSERT_PTR_NON_NULL(spline, NAN);
     356    PS_ASSERT_INT_NONNEGATIVE(spline->n, NAN);
     357    PS_ASSERT_VECTOR_TYPE(spline->knots, PS_TYPE_F32, NAN);
     358
     359    psS32 n = spline->n;
     360    if ((x < spline->knots->data.F32[0]) || (x > spline->knots->data.F32[spline->knots->n-1])) {
     361        // If x is outside the range of spline->knots, generate a warning
     362        // message, then return the left, or right, endpoint.
     363        psLogMsg(__func__, PS_LOG_WARN,
     364                 "psSpline1DEval(): x ordinate (%f) is outside the spline range (%f - %f) (%d).",
     365                 x, spline->knots->data.F32[0], spline->knots->data.F32[n-1], n);
     366
     367        psS32 binNum = (x < spline->knots->data.F32[0]) ? 0 : n-1;
     368        psTrace("psLib.math", 3, "---- %s() end ----\n", __func__);
     369        return(psPolynomial1DEval(spline->spline[binNum], x));
     370    }
     371
     372    psScalar tmpScalar;
     373    tmpScalar.type.type = PS_TYPE_F32;
     374    tmpScalar.data.F32 = x;
     375    psVectorBinaryDisectResult result;
     376    psS32 binNum = psVectorBinaryDisect(&result, spline->knots, &tmpScalar);
     377    if (result != PS_BINARY_DISECT_PASS) {
     378        psError(PS_ERR_UNKNOWN, false, "Could not perform bin dissection on spline->knots.\n");
     379        return(NAN);
     380    }
     381
     382    psTrace("psLib.math", 3, "---- %s() end ----\n", __func__);
     383    return(psPolynomial1DEval(spline->spline[binNum], x));
     384}
     385
    399386
    400387/*****************************************************************************
Note: See TracChangeset for help on using the changeset viewer.