OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
imsl_d_spline_value.c
Go to the documentation of this file.
1 /* Revision History:
2 $Log: imsl_d_spline_value.c,v $
3 Revision 6.1 2014/08/18 22:23:32 jkuyper
4 Corrected to zero-initial vector length.
5 
6 Revision 4.4 2003/08/28 16:05:59 kuyper
7 Corrected prolog.
8 
9 Revision 4.3 2003/08/26 21:23:33 kuyper
10 Corrected handling of optional arguments, to prevent use of uninitialized
11  values.
12 
13 Revision 4.2 2003/07/26 16:33:36 kuyper
14 Changed interv() to assume that calls come in non-decreasing order.
15 Changed imsl_d_spline_value() to validate that xvec is increasing.
16 Corrected sign error in bvalue().
17 Changed to return IMSL_SPLINE_ORDER_DERIV for bad values of deriv.
18 Corrected imsl_d_spline_value() to set IMSL_error_code after call to
19  imsl_d_machine(), which re-sets the code.
20 
21 Revision 4.1 2003/07/16 18:11:10 kuyper
22 Created by reverse engineering from documentation and testing of the real
23 IMSL library routine.
24 
25 */
26 #include <stdlib.h>
27 #include <float.h>
28 #include <math.h>
29 #include <stdarg.h>
30 #include "imsl_wrap.h"
31 #include "pseudo_imsl.h"
32 
33 static int interv (
34  const double xt[],
35  int lxt,
36  double x,
37  int *left
38 ){
39 
40 /*******************************************************************************
41 !C
42 !Description:
43  Sets left to the maximum value for i such that
44  xt[i] < xt[lxt-1] && xt[i] <= x
45 
46 !Input Parameters:
47  xt A double array of length lxt, assumed to be non-decreasing.
48  lxt Number of elements in the array xt.
49  x The point whose location with respect to the sequence xt is to
50  be determined.
51 
52 !Output Parameters:
53  None
54 
55 !Input/Output Parameters:
56  left On input, points to an initial guess, assumed to be
57  non-negative, for the final value to be written over that guess.
58  This code assumes 0<= *left < lxt.
59  On output, the int that it points at is set to:
60  0 if x < xt[0]
61  i if xt[i] <= x < xt[i+1]
62  i if xt[i] < x < xt[i+1] == xt[lxt1-1]
63  i if xt[i] < xt[i+1] == xt[lxt-1] < x
64 
65  The asymmetric treatment of the intervals is due to the decision to
66  make all pp functions continuous from the right.
67 
68 
69 Return Value:
70  -1 if x < xt[0]
71  1 if xt[lxt-1] < x
72  0 otherwise (the usual case)
73 
74  By returning 0 even if x==xt[lxt-1], there is the option of having the
75  computed pp function continuous from the left at xt[lxt].
76 
77 Externally Defined:
78  None
79 
80 Called by:
81  bvalue
82 
83 Routines Called:
84  None
85 
86 !Revision History:
87 See top of file
88 
89 !Team-unique Header:
90  This software is developed by the MODIS Science Data Support
91  Team for the National Aeronautics and Space Administration,
92  Goddard Space Flight Center, under contract NAS5-32373.
93 
94 References and Credits
95  This routine is based loosley upon the Fortran routine of the same name
96  as described by Carl de Boor in "A Practical Guide to Splines - Revised
97  Edition", 2001. The original routine can be found in interv.f, which is
98  part of the pppack package which can be downloaded from
99  <ftp://netlib.bell-labs.com/netlib/pppack.tar>
100 
101 Design Notes
102  The function is designed to be efficient in the common situation that
103  it is called repeatedly, with x taken from an increasing sequence. This
104  will happen, e.g., when a pp function is to be graphed. The first guess
105  pointed at by 'left' should therefore normally be the value returned
106  through that same parameter from the previous call. Then, if
107  xt[ilo] <= x < xt[ilo+1], we set left = ilo and are done after just
108  three comparisons.
109  Otherwise, we repeatedly double the difference istep = ihi - ilo while
110  also moving ihi in the direction of x, until
111  xt[ilo] <= x < xt[ihi]
112  after which we use bisection to get, in addition, ilo+1 = ihi.
113  *left = ilo is then returned.
114 
115  This version differs from the original in that *left is used to
116  initialize ilo, rather than making ilo static. This allows multiple
117  different searches through different tables (or even the same table) to
118  alternate with each other without interference. More importantly, it
119  allows *left to be externally re-initialized when the table changes.
120  Since it is externally initialized, *left is assumet to always be in a
121  valid range for the current table. Finally, it is assumed that each
122  table is accessed in increasing order.
123 !END**************************************************************************
124 */
125  int ilo = *left;
126  int ihi=ilo+1, middle;
127 
128  while(ihi < lxt-1 && x >= xt[ihi])
129  /* Increase ihi to capture x. */
130  ihi = 2*ihi-ilo;
131 
132  if(ihi > lxt-1)
133  ihi = lxt-1;
134 
135  while(ihi > ilo+1)
136  {
137  /* Narrow the interval. */
138  middle = (ihi+ilo)/2;
139  if(x > xt[middle])
140  ilo = middle;
141  else
142  ihi = middle;
143  }
144 
145  *left = ilo;
146  /* Set return flag. */
147  if(x < xt[0])
148  return -1;
149 
150  if(x > xt[lxt-1])
151  return 1;
152 
153  return 0;
154 
155 }
156 
157 static double bvalue(
158  const double t[/*n+k*/],
159  const double bcoef[/*n*/],
160  int n,
161  int k,
162  double x,
163  int jderiv,
164  int *pi
165 ){
166 /*******************************************************************************
167 !C
168 !Description:
169  Calculates the value at x of the jderiv-th derivative of the spline
170  described by t, bcoef, n, and k. The spline is taken to be continuous
171  from the right, EXCEPT at the rightmost knot, where it is taken to be
172  continuous from the left.
173 
174 !Input Parameters:
175  t knot sequence, of length n+k, assumed nondecreasing
176  bcoef b-coefficient sequence, of length n.
177  n length of bcoef and dimension of spline(k,t), ASSUMED positive.
178  k order of the spline.
179  WARNING: the restriction k < MAX_SPLINE_ORDER is imposed
180  arbitrarily by the declarations of aj, dl, dr below, but is
181  NOWHERE CHECKED for.
182  x The point at which to evaluate.
183  jderiv Integer giving the order of the derivative to be evaluated.
184  ASSUMED to be zero or positive.
185 
186 !Output Parameters:
187  None
188 
189 !Input/Output Parameters:
190  pi On input: points at an estimate of the location for x in t[],
191  usually the value returned by a previous call to this function.
192  On output: The left side of the bracketing location for x, as
193  returned by interv().
194 
195 Return Value:
196  The value of the (jderiv)-th derivative of f at x.
197 
198 Externally Defined:
199  MAX_SPLINE_ORDER "pseudo_imsl.h"
200 
201 Called by:
202  imsl_d_spline_value
203 
204 Routines Called:
205  interv imsl_d_spline_value.c
206 
207 !Revision History:
208 See top of file.
209 
210 Requirements:
211  None
212 
213 !Team-unique Header:
214  This software is developed by the MODIS Science Data Support
215  Team for the National Aeronautics and Space Administration,
216  Goddard Space Flight Center, under contract NAS5-32373.
217 
218 References and Credits
219  "A Practical Guide to Splines - Revised edition", Carl de Boor,
220  copyright 2001
221  <http://netlib.bell-labs.com/netlib/master/readme.htm>
222 
223 Design Notes
224  This is a port to C of the FORTRAN routine named bvalue() described in
225  de Boor (2001). That routine is provided in the bvalue.f file which is
226  part of the pppack package which can be downloaded from the netlib web
227  site listed above.
228 
229  The nontrivial knot interval t[i], t[i+1] containing x is located with
230  the aid of interv(). The k b-coeffs of f relevant for this interval are
231  then obtained from bcoef (or taken to be zero if not explicitly
232  available) and are then differenced jderiv times to obtain the b-coeffs
233  of (d**jderiv)f relevant for that interval. Precisely, with j=jderiv,
234  we have from X.12 of de Boors (2001) that
235 
236  (d**j)f = sum ( bcoef[.,j]*b[.,k-j,t] )
237 
238  where
239 
240  | bcoef[.] j==0
241  |
242  bcoef[.,j] =| bcoef[.,j-1] - bcoef[.-1,j-1]
243  | -----------------------------, j > 0
244  | (t[.+k-j] - t[.])/(k-j)
245 
246  Then, we use repeatedly the fact that
247 
248  sum( a[.]*b[.,m,t](x) ) = sum(a[.,x]*b[.,m-1,t](x) )
249 
250  with
251 
252  (x - t[.])*a[.] + (t[.+m-1] - x)*a[.-1]
253  a[.,x] = ---------------------------------------
254  (x - t[.]) + (t[.+m-1] - x)
255 
256  to write (d**j)f(x) eventually as a linear combination of b-splines of
257  order 1, and the coefficient for b[i,1,t](x) must then be the desired
258  number (d**j)f(x). (See X.17-X.19 of de Boors (2001)).
259 
260  This function makes many unchecked assumptions, including both the ones
261  explicitly mentioned above, and the assumption that its pointer
262  arguments are valid. The validity of those assumptions is the
263  responsibility of the calling function. Therefore, this function has
264  been made static, so it can only be called by other functions in the
265  same file. This will make it easier to verify that the the calling
266  function fulfills its responsibility.
267 !END**************************************************************************
268 */
270  double fkmj;
271  int i, ilo, imk, j, jc, jcmin, jcmax, jj, kmj, km1, nmi;
272 
273  if(jderiv >= k)
274  return 0.0;
275 
276  /* Find i s.t. 0 <= i < n+k-1 AND t[i] < t[i+1] and t[i] <= x < t[i+1]. If
277  * no such i can be found, x lies outside the support of the spline f,
278  * hence bvalue = 0.
279  * The asymmetry in this choice of i makes f rightcontinuous, except at
280  * t[n+k-1] where it is leftcontinuous.)
281  */
282  if(interv(t, n+k, x, pi)!=0)
283  return 0.0;
284 
285  i = *pi;
286  km1 = k - 1;
287  if(km1 <= 0)
288  return bcoef[i];
289 
290  /* Store the k b-spline coefficients relevant for the knot interval
291  * (t[i], t[i+1]) in aj[0],...,aj[k-1] and compute dl[j] = x - t[i+1-j],
292  * from input to zero. Set any t's not obtainable equal to t[0] or to t[n+k]
293  * appropriately.
294  */
295  jcmin = 0;
296  imk = i - k + 1;
297  if(imk < 0)
298  {
299  jcmin = -imk;
300  for(j=0; j<=i; j++)
301  dl[j] = x - t[i-j];
302  for(j=i; j<km1; j++)
303  {
304  aj[k-j-2] = 0.0;
305  dl[j] = dl[i];
306  }
307  }
308  else
309  for(j=0; j<km1; j++)
310  dl[j] = x - t[i-j];
311 
312  jcmax = k;
313  nmi = n - i;
314  if(nmi < 1)
315  {
316  jcmax = k + nmi - 1;
317  for(j=0; j<jcmax; j++)
318  dr[j] = t[i+j+1] - x;
319  for(j=jcmax-1; j< km1; j++)
320  {
321  aj[j+1] = 0.0;
322  dr[j] = dr[jcmax-1];
323  }
324  }
325  else
326  for(j=0; j<km1; j++)
327  dr[j] = t[i+j+1] - x;
328 
329  for(jc=jcmin; jc<jcmax; jc++)
330  aj[jc] = bcoef[imk+jc];
331 
332  /* Difference the coefficients jderiv times */
333  for(j=1; j<=jderiv; j++)
334  {
335  kmj = k - j;
336  fkmj = (double)kmj;
337  ilo = kmj;
338  for(jj=1; jj<=kmj; jj++)
339  aj[jj-1] = ((aj[jj] - aj[jj-1])/(dl[--ilo] + dr[jj-1]))*fkmj;
340  }
341 
342  /* Compute value at x in (t[i],t[i+1]) of jderiv-th derivative,
343  * give its relevant b-spline coeffs in aj[0],...,aj[k-jderiv].
344  */
345  for(j=jderiv; j<km1; j++) /* Double check these limits. */
346  {
347  kmj = k - j - 1;
348  ilo = kmj;
349  for(jj=0; jj<kmj; jj++) /* Double check limits. */
350  {
351  --ilo;
352  aj[jj] = (aj[jj+1]*dl[ilo] + aj[jj]*dr[jj])/(dl[ilo] + dr[jj]);
353  }
354 
355  }
356 
357  return aj[0];
358 }
359 
360 double IMSL_DECL imsl_d_machine(
361  int n
362 ){
363 /*******************************************************************************
364 !C
365 !Description:
366  Returns information describing the computer's double precision
367  floating-point arithmetic.
368 
369 !Input Parameters:
370  n Index indicating which value is to be returned. The index must
371  be from 1 to 8, inclusive.
372 
373 !Output Parameters:
374  None
375 
376 Return Value:
377  n Value returned
378  ---- -----------------
379  1 The smallest positive number.
380  2 The largest number
381  3 The smallest relative spacing.
382  4 The largest relative spacing.
383  5 log10(floating point radix)
384  6 NaN (not a number)
385  7 positive machine infinity
386  8 negative machine infinity
387  other NaN
388 
389  On machines that do not support NaN, imsl_d_machine(6) returns a value
390  larger than imsl_d_machine(2). On machines which do not have a special
391  representation for infinity, imsl_d_machine(2)==imsl_d_machine(7).
392 
393 Externally Defined:
394  __STDC_VERSION__ Defined by compiler (C94 or later)
395  DBL_EPSILON <float.h>
396  DBL_MAX <float.h>
397  DBL_MIN <float.h>
398  FLT_RADIX <float.h>
399  HUGE_VAL <math.h>
400  Imsl_code "imsl_wrap.h"
401  IMSL_DECL "imsl_wrap.h"
402  IMSL_error_code "pseudo_imsl.h"
403  IMSL_INTEGER_OUT_OF_RANGE "imsl_wrap.h"
404 
405 Called by:
406  GEO_prepare_mirr_data
407  GEO_interp_mirr_enc
408  imsl_d_spline_value
409 
410 Routines Called:
411  None
412 
413 !Revision History:
414 See top of file.
415 
416 Requirements:
417  None
418 
419 !Team-unique Header:
420  This software is developed by the MODIS Science Data Support
421  Team for the National Aeronautics and Space Administration,
422  Goddard Space Flight Center, under contract NAS5-32373.
423 
424 References and Credits
425  Reverse engineered from:
426  "IMSL C/Math/Library", copyright Visual Numerics, Inc. 1999-2001
427 
428 Design Notes
429 !END**************************************************************************
430 */
431 
432 /* The nan() function was introduced in C99. It's defined to return a quiet NaN
433  * if the implementation supports quiet NaNs, and to otherwise return 0.0.
434  */
435 #if __STDC_VERSION__ < 199901L
436 #define IMSL_NAN HUGE_VAL
437 #else
438 #define IMSL_NAN (nan("")==0.0 ? HUGE_VAL : nan(""))
439 #endif
440 
441  IMSL_error_code = (Imsl_code)0;
442 
443  switch(n)
444  {
445  case 1: return DBL_MIN;
446 
447  case 2:
448  if(IMSL_NAN!=HUGE_VAL || DBL_MAX < HUGE_VAL)
449  return DBL_MAX;
450 #if __STDC_VERSION__ < 199901L
451  /* Note: for C90, __STDC_VERSION__ is not defined, which counts as
452  * a 0 in #if statements, which achieves exactly the desired result.
453  */
454  return DBL_MAX*(1.0-DBL_EPSILON);
455 #else
456  return nextafter(DBL_MAX, 0.0);
457 #endif
458 
459  case 3: return DBL_EPSILON/FLT_RADIX;
460  case 4: return DBL_EPSILON;
461  case 5: return log10(FLT_RADIX);
462 
463  case 7:
464  if(IMSL_NAN!=HUGE_VAL || DBL_MAX < HUGE_VAL)
465  return HUGE_VAL;
466 #if __STDC_VERSION__ < 199901L
467  return HUGE_VAL*(1.0-DBL_EPSILON);
468 #else
469  return nextafter(HUGE_VAL, 0.0);
470 #endif
471 
472  case 8: return -HUGE_VAL;
473 
474  default:
475  IMSL_error_code = IMSL_INTEGER_OUT_OF_RANGE; /* undocumented */
476  /* FALL through to next case */
477  case 6:
478  return IMSL_NAN;
479  }
480 }
481 
482 double IMSL_DECL imsl_d_spline_value(
483  double x,
484  Imsl_d_spline *sp,
485  ...
486 ){
487 /*******************************************************************************
488 !C
489 !Description:
490  Calculates the value of a spline or the value of one of its derivatives.
491 
492 !Input Parameters:
493  x Evaluation point for the spline. Ignored if the IMSL_GRID_USER
494  option is selected (undocumented).
495  sp Pointer to the structure that represents the spline.
496  ... One or more sets of optional arguments are accepted, using the
497  C <stdarg.h> interface, each starting with an int argument that
498  identifies the type of the set. The permitted sets of optional
499  arguments are:
500 
501  int IMSL_DERIV Indicates that the following argument is:
502  int deriv The derivative of the spline to be computed.
503  default = 0.
504 
505  int 0 Indicates the end of the list of arguments
506 
507 !Output Parameters:
508  None.
509 
510 !Input/Output Parameters:
511  int IMSL_GRID_USER Indicates that the next three arguments are:
512  int n The length of the xvec array
513  const double xvec[] The evaluation points for the spline
514  double value_user[] The location where the values are to be written
515 
516 Return Value:
517  The value of the spline or one of its derivatives at the point x.
518  If no value can be computed, imsl_d_machine(6) is returned instead.
519  That same value is also returned if the the IMSL_GRID_USER option is
520  chosen (undocumented).
521  imsl_d_machine(6) is a NaN, if possible. If not, it's a normally valid
522  value that the IMSL functions treat as if it were a true NaN.
523 
524 Externally Defined:
525  DBL_MAX <float.h>
526  Imsl_code "imsl_wrap.h"
527  IMSL_DECL "imsl_wrap.h"
528  IMSL_DERIV "imsl_wrap.h"
529  IMSL_error_code "pseudo_imsl.h"
530  IMSL_GRID_USER "imsl_wrap.h"
531  IMSL_KNOT_MULTIPLICITY "imsl_wrap.h"
532  IMSL_KNOT_NOT_INCREASING "imsl_wrap.h"
533  IMSL_SPLINE_BAD_COEFFS "imsl_wrap.h"
534  IMSL_SPLINE_BAD_ORDER "imsl_wrap.h"
535  IMSL_SPLINE_ORDER_DERIV "imsl_wrap.h"
536  IMSL_UNEXPECTED_NULL_POINTER "imsl_wrap.h"
537  IMSL_UNKNOWN_OPTION "imsl_wrap.h"
538  IMSL_XVEC_LENGTH "imsl_wrap.h"
539  IMSL_XVEC_NOT_INCREASING "imsl_wrap.h"
540  MAX_SPLINE_ORDER "pseudo_imsl.h"
541 
542 Called by:
543  GEO_interp_mirr_enc
544  GEO_prepare_mirr_data
545 
546 Routines Called:
547  bvalue imsl_d_spline_value.c
548  imsl_d_machine "imsl_wrap.h"
549 
550 !Revision History:
551 See top of file
552 
553 Requirements:
554  None
555 
556 !Team-unique Header:
557  This software is developed by the MODIS Science Data Support
558  Team for the National Aeronautics and Space Administration,
559  Goddard Space Flight Center, under contract NAS5-32373.
560 
561 References and Credits
562  "IMSL C/Math/Library", copyright 1990-2001.
563  "A Practical Guide to Splines - Revised edition", Carl de Boor,
564  copyright 2001
565 
566 Design Notes
567  This function is a wrapper for a modified C version of the Fortran
568  bvalue() function described in de Boor (2001).
569 
570  The interface is intended to mimic a subset of the features of the
571  correspondingly named IMSL library function. That will allow us to make
572  the use of the actual IMSL library optional, without requiring a
573  re-write of the code that uses the function.
574 
575  This function's interface differs from that of the real
576  imsl_d_spline_value() in that the IMSL_GRID option is not supported.
577 !END**************************************************************************
578 */
579  va_list ap; /* see <stdarg.h> */
580  const double *xvec=NULL;
581  double *value_user=NULL, epsilon, imsl_nan=imsl_d_machine(6);
582  int i=0, grid=0, deriv=0;
583  int arg, knot, n=0, num_knots, val;
584 
585  IMSL_error_code = (Imsl_code)0;
586  va_start(ap, sp);
587 
588  while(( arg=va_arg(ap,int) )) /* = rather than == is deliberate */
589  {
590  if(arg == IMSL_DERIV)
591  deriv = va_arg(ap,int);
592  else if(arg == IMSL_GRID_USER)
593  {
594  n = va_arg(ap,int);
595  xvec = (const double *)va_arg(ap,double *);
596  value_user = va_arg(ap, double*);
597  grid = 1;
598  }
599  else
600  {
601  IMSL_error_code = IMSL_UNKNOWN_OPTION; /* undocumented. */
602  return imsl_nan;
603  }
604  }
605  va_end(ap);
606 
607  if(sp==NULL || sp->order==NULL || sp->num_coef==NULL || sp->knots==NULL ||
608  sp->coef==NULL || sp->knots[0]==NULL || sp->coef[0] == NULL)
609  {
610  /* IMSL doesn't actually test this. */
611  IMSL_error_code = IMSL_UNEXPECTED_NULL_POINTER;
612  return imsl_nan;
613  }
614 
615  /* The real IMSL function does not verify that sp->domain_dim==1 or
616  * sp->target_dim==1, therefore we don't have to.
617  */
618 
619  if(sp->order[0] < 1 || sp->order[0] > MAX_SPLINE_ORDER)
620  {
621  /* The upper limit is specific to pseudo-IMSL. */
622  IMSL_error_code = IMSL_SPLINE_BAD_ORDER; /* undocumented. */
623  return imsl_nan;
624  }
625 
626  if(sp->num_coef[0] < sp->order[0])
627  {
628  IMSL_error_code = IMSL_SPLINE_BAD_COEFFS; /* undocumented. */
629  return imsl_nan;
630  }
631 
632  if(deriv < 0)
633  {
634  IMSL_error_code = IMSL_SPLINE_ORDER_DERIV; /* undocumented. */
635  return imsl_nan;
636  }
637 
638  num_knots = sp->num_coef[0] + sp->order[0];
639  /* The above calculation removes the need to validate that
640  * sp->num_knots[0] == sp->num_coef[0]+sp->order[0]
641  * a validity test which the real IMSL function doesn't make.
642  */
643 
644  /* The real IMSL function uses the equivalent of epsilon=0.0, in order to
645  * avoid division by zero. Setting epsilon to this particular value allows
646  * us to also avoid division by numbers that are so small that the division
647  * could overflow.
648  */
649  epsilon = pow((sp->knots[0][num_knots-1] - sp->knots[0][0])/DBL_MAX,
650  1.0/(double)sp->order[0]);
651 
652  /* Validate that knots are non-decreasing. */
653  for(knot=0; knot<num_knots-1; knot++)
654  {
655  if(sp->knots[0][knot] > sp->knots[0][knot+1])
656  {
657  /* This mnemonic is mis-named. */
658  IMSL_error_code = IMSL_KNOT_NOT_INCREASING;
659  return imsl_nan;
660  }
661  }
662 
663  /* Validate that there are never more than sp->order[0] knots at (almost)
664  * the same location.
665  */
666  for(knot=0; knot<sp->num_coef[0]; knot++)
667  {
668  if(sp->knots[0][knot+sp->order[0]] - sp->knots[0][knot] <= epsilon)
669  {
670  IMSL_error_code = IMSL_KNOT_MULTIPLICITY;
671  return imsl_nan;
672  }
673  }
674 
675  if(grid==0)
676  {
677  /* Only need to evaluate for x. */
678  return bvalue(sp->knots[0], sp->coef[0], sp->num_coef[0], sp->order[0],
679  x, deriv, &i);
680  }
681 
682  if(xvec==NULL || value_user==NULL)
683  {
684  /* IMSL doesn't actually make this test. */
685  IMSL_error_code = IMSL_UNEXPECTED_NULL_POINTER;
686  return imsl_nan;
687  }
688 
689  if(n < 1)
690  {
691  IMSL_error_code = IMSL_XVEC_LENGTH; /* Undocumented. */
692  return imsl_nan;
693  }
694 
695  for(val=0; val<n; val++)
696  {
697  if(val && xvec[val] <= xvec[val-1])
698  {
699  IMSL_error_code = IMSL_XVEC_NOT_INCREASING; /* Undocumented */
700  break;
701  }
702 
703  value_user[val] = bvalue(sp->knots[0], sp->coef[0], sp->num_coef[0],
704  sp->order[0], xvec[val], deriv, &i);
705  }
706 
707  return imsl_nan;
708 }
709 
data_t t[NROOTS+1]
Definition: decode_rs.h:77
int j
Definition: decode_rs.h:73
#define MAX_SPLINE_ORDER
Definition: pseudo_imsl.h:52
#define NULL
Definition: decode_rs.h:63
double IMSL_DECL imsl_d_machine(int n)
const double pi
double IMSL_DECL imsl_d_spline_value(double x, Imsl_d_spline *sp,...)
Imsl_code IMSL_error_code
Definition: imsl_error.c:20
#define IMSL_NAN
integer, parameter double
#define DBL_MAX
Definition: make_L3_v1.1.c:60
int i
Definition: decode_rs.h:71
msiBandIdx val
Definition: l1c_msi.cpp:34
int k
Definition: decode_rs.h:73