ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/data.c
(Generate patch)

Comparing ray/src/rt/data.c (file contents):
Revision 2.36 by greg, Wed Dec 13 23:26:16 2023 UTC vs.
Revision 2.37 by greg, Tue Mar 12 16:54:51 2024 UTC

# Line 374 | Line 374 | freedata(                      /* release data array reference */
374                  hval = 0; nents = TABSIZ;
375          } else {
376                  hval = hash(dta->name); nents = 1;
377 +                if (!*dta->name) {              /* not a data file? */
378 +                        dta->next = dtab[hval];
379 +                        dtab[hval] = dta;       /* ...fake position */
380 +                }
381          }
382          while (nents--) {
383                  head.next = dtab[hval];
# Line 394 | Line 398 | freedata(                      /* release data array reference */
398   }
399  
400  
401 + /* internal call to interpolate data value or vector */
402 + static double
403 + data_interp(DATARRAY *dp, double *pt, double coef, DATATYPE *rvec)
404 + {
405 +        DATARRAY        sd;
406 +        int             stride, i;
407 +        double          x, c0, c1, y0, y1;
408 +                                        /* set up dimensions for recursion */
409 +        if (dp->nd > 1) {
410 +                sd.name = dp->name;
411 +                sd.type = dp->type;
412 +                sd.nd = dp->nd - 1;
413 +                memcpy(sd.dim, dp->dim+1, sd.nd*sizeof(struct dadim));
414 +                stride = sd.dim[i = sd.nd-1].ne + (sd.type==SPECTY);
415 +                while (i-- > 0)
416 +                        stride *= sd.dim[i].ne;
417 +        }
418 +                                        /* get independent variable */
419 +        if (dp->dim[0].p == NULL) {             /* evenly spaced points */
420 +                x = (pt[0] - dp->dim[0].org)/dp->dim[0].siz;
421 +                x *= (double)(dp->dim[0].ne - 1);
422 +                i = x;
423 +                if (i < 0)
424 +                        i = 0;
425 +                else if (i > dp->dim[0].ne - 2)
426 +                        i = dp->dim[0].ne - 2;
427 +        } else {                                /* unevenly spaced points */
428 +                int     lower, upper;
429 +                if (dp->dim[0].siz > 0.0) {
430 +                        lower = 0;
431 +                        upper = dp->dim[0].ne;
432 +                } else {
433 +                        lower = dp->dim[0].ne;
434 +                        upper = 0;
435 +                }
436 +                do {
437 +                        i = (lower + upper) >> 1;
438 +                        if (pt[0] >= dp->dim[0].p[i])
439 +                                lower = i;
440 +                        else
441 +                                upper = i;
442 +                } while (i != (lower + upper) >> 1);
443 +
444 +                if (i > dp->dim[0].ne - 2)
445 +                        i = dp->dim[0].ne - 2;
446 +
447 +                x = i + (pt[0] - dp->dim[0].p[i]) /
448 +                                (dp->dim[0].p[i+1] - dp->dim[0].p[i]);
449 +        }
450 +        /*
451 +         * Compute interpolation coefficients:
452 +         * extrapolate as far as one division, then
453 +         * taper off harmonically to zero.
454 +         */
455 +        if (x > i+2) {
456 +                c0 = 1./(i-1 - x);
457 +                c1 = -2.*c0;
458 +        } else if (x < i-1) {
459 +                c1 = 1./(i - x);
460 +                c0 = -2.*c1;
461 +        } else {
462 +                c0 = i+1 - x;
463 +                c1 = x - i;
464 +        }
465 +        c0 *= coef;
466 +        c1 *= coef;
467 +                                        /* check if vector interp */
468 +        if ((dp->nd == 2) & (rvec != NULL)) {
469 +                if (dp->type == DATATY) {
470 +                        sd.arr.d = dp->arr.d + i*stride;
471 +                        for (i = sd.dim[0].ne; i--; )
472 +                                rvec[i] += c0*sd.arr.d[i]
473 +                                        + c1*sd.arr.d[i+stride];
474 +                        return(0.);
475 +                }
476 +                if (dp->type == SPECTY) {
477 +                        double  f;
478 +                        sd.arr.s = dp->arr.s + i*stride;
479 +                        f = ldexp(1.0, (int)sd.arr.s[sd.dim[0].ne]
480 +                                        - (COLXS+8));
481 +                        for (i = sd.dim[0].ne; i--; )
482 +                                rvec[i] += c0*f*(sd.arr.s[i] + 0.5);
483 +                        sd.arr.s += stride;
484 +                        f = ldexp(1.0, (int)sd.arr.s[sd.dim[0].ne]
485 +                                        - (COLXS+8));
486 +                        for (i = sd.dim[0].ne; i--; )
487 +                                rvec[i] += c1*f*(sd.arr.s[i] + 0.5);
488 +                        return(0.);
489 +                }
490 +                sd.arr.c = dp->arr.c + i*stride;
491 +                for (i = sd.dim[0].ne; i--; )
492 +                        rvec[i] += c0*colrval(sd.arr.c[i],sd.type)
493 +                                + c1*colrval(sd.arr.c[i+stride],sd.type);
494 +                return(0.);
495 +        }
496 +                                        /* get dependent variable */
497 +        if (dp->nd > 1) {
498 +                if (dp->type == DATATY) {
499 +                        sd.arr.d = dp->arr.d + i*stride;
500 +                        y0 = data_interp(&sd, pt+1, c0, rvec);
501 +                        sd.arr.d += stride;
502 +                } else if (dp->type == SPECTY) {
503 +                        sd.arr.s = dp->arr.s + i*stride;
504 +                        y0 = data_interp(&sd, pt+1, c0, rvec);
505 +                        sd.arr.s += stride;
506 +                } else {
507 +                        sd.arr.c = dp->arr.c + i*stride;
508 +                        y0 = data_interp(&sd, pt+1, c0, rvec);
509 +                        sd.arr.c += stride;
510 +                }
511 +                y1 = data_interp(&sd, pt+1, c1, rvec);
512 +        } else {                        /* end of recursion */
513 +                if (dp->type == DATATY) {
514 +                        y0 = dp->arr.d[i];
515 +                        y1 = dp->arr.d[i+1];
516 +                } else if (dp->type == SPECTY) {
517 +                        if (dp->arr.s[dp->dim[0].ne]) {
518 +                                double  f = ldexp(1.0, -(COLXS+8) +
519 +                                                (int)dp->arr.s[dp->dim[0].ne]);
520 +                                y0 = (dp->arr.s[i] + 0.5)*f;
521 +                                y1 = (dp->arr.s[i+1] + 0.5)*f;
522 +                        } else
523 +                                y0 = y1 = 0.0;
524 +                } else {
525 +                        y0 = colrval(dp->arr.c[i],dp->type);
526 +                        y1 = colrval(dp->arr.c[i+1],dp->type);
527 +                }
528 +                y0 *= c0;
529 +                y1 *= c1;
530 +        }
531 +        return(y0 + y1);        /* coefficients already applied */
532 + }
533 +
534 +
535   double
536   datavalue(              /* interpolate data value at a point */
537          DATARRAY  *dp,
538          double  *pt
539   )
540   {
541 +        return(data_interp(dp, pt, 1., NULL));
542 + }
543 +
544 +
545 + /* Interpolate final vector corresponding to last dimension in data array */
546 + DATARRAY *
547 + datavector(DATARRAY *dp, double *pt)
548 + {
549 +        DATARRAY        *newdp;
550 +
551 +        if (dp->nd < 2)
552 +                error(INTERNAL, "datavector() called with 1-D array");
553 +                                        /* create vector array */
554 +        newdp = (DATARRAY *)malloc(sizeof(DATARRAY) -
555 +                                (MAXDDIM-1)*sizeof(struct dadim) +
556 +                                sizeof(DATATYPE)*dp->dim[dp->nd-1].ne);
557 +        if (newdp == NULL)
558 +                error(SYSTEM, "out of memory in datavector");
559 +        newdp->next = NULL;
560 +        newdp->name = dp->name;
561 +        newdp->type = DATATY;
562 +        newdp->nd = 1;                  /* vector data goes here */
563 +        newdp->dim[0] = dp->dim[dp->nd-1];
564 +        newdp->arr.d = (DATATYPE *)(newdp->dim + 1);
565 +        memset(newdp->arr.d, 0, sizeof(DATATYPE)*newdp->dim[0].ne);
566 +
567 +        (void)data_interp(dp, pt, 1., newdp->arr.d);
568 +
569 +        return(newdp);                  /* will be free'd using free() */
570 + }
571 +
572 +
573 + #if 0
574 + double
575 + datavalue(              /* interpolate data value at a point */
576 +        DATARRAY  *dp,
577 +        double  *pt
578 + )
579 + {
580          DATARRAY  sd;
581          int  asize;
582          int  lower, upper;
# Line 497 | Line 674 | datavalue(             /* interpolate data value at a point */
674  
675          return( y0*((i+1)-x) + y1*(x-i) );
676   }
677 + #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines