BRL-CAD
tabdata.h
Go to the documentation of this file.
1 /* T A B D A T A . H
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2024 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 /*----------------------------------------------------------------------*/
22 /** @addtogroup bn_tabdata
23  *
24  * @brief
25  * Routines for processing tables (curves) of data with one independent
26  * parameter which is common to many sets of dependent data values.
27  *
28  * Data structures to assist with recording many sets of data sampled
29  * along the same set of independent variables.
30  *
31  * The overall notion is that each sample should be as compact as
32  * possible (an array of measurements), with all the context stored in
33  * one place.
34  *
35  * These structures and support routines apply to any measured "curve"
36  * or "function" or "table" with one independent variable and one or
37  * more scalar dependent variable(s).
38  *
39  * The context is kept in an 'bn_table' structure, and the data for
40  * one particular sample are kept in an 'bn_tabdata' structure.
41  *
42  * The contents of the sample in val[j] are interpreted in the
43  * interval (wavel[j]..wavel[j+1]). This value could be power,
44  * albedo, absorption, refractive index, or any other
45  * wavelength-specific parameter.
46  *
47  * For example, if the val[] array contains power values, then val[j]
48  * contains the integral of the power from wavel[j] to wavel[j+1]
49  *
50  * As an example, assume nwave=2, wavel[0]=500, wavel[1]=600, wavel[2]=700.
51  * Then val[0] would contain data for the 500 to 600nm interval,
52  * and val[1] would contain data for the 600 to 700nm interval.
53  * There would be no storage allocated for val[2] -- don't use it!
54  * There are several interpretations of this:
55  * 1) val[j] stores the total (integral, area) value for the interval, or
56  * 2) val[j] stores the average value across the interval.
57  *
58  * The intervals need not be uniformly spaced; it is acceptable to
59  * increase wavelength sampling density around "important"
60  * frequencies.
61  *
62  * Operates on bn_table (independent var) and
63  * bn_tabdata (dependent variable) structures.
64  *
65  * One application is for storing spectral curves, see spectrum.c
66  *
67  * @par Inspired by -
68  * Roy Hall and his book "Illumination and Color in Computer
69  *@n Generated Imagery", Springer Verlag, New York, 1989.
70  *@n ISBN 0-387-96774-5
71  *
72  * With thanks to Russ Moulton Jr, EOSoft Inc. for his "rad.c" module.
73  */
74 /** @{ */
75 /* @file bn/tabdata.h */
76 
77 #ifndef BN_TABDATA_H
78 #define BN_TABDATA_H
79 
80 #include "common.h"
81 
82 #include "vmath.h"
83 
84 #include "bn/defines.h"
85 #include "bu/magic.h"
86 #include "bu/vls.h"
87 
88 __BEGIN_DECLS
89 
90 struct bn_table {
91  uint32_t magic;
92  size_t nx;
93  fastf_t x[1]; /**< @brief array of nx+1 wavelengths, dynamically sized */
94 };
95 
96 #define BN_CK_TABLE(_p) BU_CKMAG(_p, BN_TABLE_MAGIC, "bn_table")
97 #define BN_TABLE_NULL ((struct bn_table *)NULL)
98 
99 /* Gets an bn_table, with x[] having size _nx+1 */
100 #ifndef NO_BOMBING_MACROS
101 # define BN_GET_TABLE(_table, _nx) { \
102  if ((_nx) < 1) bu_bomb("RT_GET_TABLE() _nx < 1\n"); \
103  _table = (struct bn_table *)bu_calloc(1, \
104  sizeof(struct bn_table) + sizeof(fastf_t)*(_nx), \
105  "struct bn_table"); \
106  _table->magic = BN_TABLE_MAGIC; \
107  _table->nx = (_nx); }
108 #else
109 # define BN_GET_TABLE(_table, _nx) { \
110  _table = (struct bn_table *)bu_calloc(1, \
111  sizeof(struct bn_table) + sizeof(fastf_t)*(_nx), \
112  "struct bn_table"); \
113  _table->magic = BN_TABLE_MAGIC; \
114  _table->nx = (_nx); }
115 #endif
116 
117 struct bn_tabdata {
118  uint32_t magic;
119  size_t ny;
120  const struct bn_table *table; /**< @brief Up pointer to definition of X axis */
121  fastf_t y[1]; /**< @brief array of ny samples, dynamically sized */
122 };
123 #define BN_CK_TABDATA(_p) BU_CKMAG(_p, BN_TABDATA_MAGIC, "bn_tabdata")
124 #define BN_TABDATA_NULL ((struct bn_tabdata *)NULL)
125 
126 #define BN_SIZEOF_TABDATA_Y(_tabdata) sizeof(fastf_t)*((_tabdata)->ny)
127 #define BN_SIZEOF_TABDATA(_table) (sizeof(struct bn_tabdata) + \
128  sizeof(fastf_t)*((_table)->nx-1))
129 
130 /* Gets an bn_tabdata, with y[] having size _ny */
131 #define BN_GET_TABDATA(_data, _table) { \
132  BN_CK_TABLE(_table);\
133  _data = (struct bn_tabdata *)bu_calloc(1, \
134  BN_SIZEOF_TABDATA(_table), "struct bn_tabdata"); \
135  _data->magic = BN_TABDATA_MAGIC; \
136  _data->ny = (_table)->nx; \
137  _data->table = (_table); }
138 
139 /*
140  * Routines
141  */
142 
143 
144 BN_EXPORT extern void bn_table_free(struct bn_table *tabp);
145 
146 BN_EXPORT extern void bn_tabdata_free(struct bn_tabdata *data);
147 
148 BN_EXPORT extern void bn_ck_table(const struct bn_table *tabp);
149 
150 /*
151  *@brief
152  * Set up an independent "table margin" from 'first' to 'last',
153  * inclusive, using 'num' uniformly spaced samples. Num >= 1.
154  */
155 BN_EXPORT extern struct bn_table *bn_table_make_uniform(size_t num,
156  double first,
157  double last);
158 
159 /*
160  *@brief
161  * Sum the values from two data tables.
162  */
163 BN_EXPORT extern void bn_tabdata_add(struct bn_tabdata *out,
164  const struct bn_tabdata *in1,
165  const struct bn_tabdata *in2);
166 
167 /*
168  *@brief
169  * Element-by-element multiply the values from two data tables.
170  */
171 BN_EXPORT extern void bn_tabdata_mul(struct bn_tabdata *out,
172  const struct bn_tabdata *in1,
173  const struct bn_tabdata *in2);
174 
175 /*
176  *@brief
177  * Element-by-element multiply the values from three data tables.
178  */
179 BN_EXPORT extern void bn_tabdata_mul3(struct bn_tabdata *out,
180  const struct bn_tabdata *in1,
181  const struct bn_tabdata *in2,
182  const struct bn_tabdata *in3);
183 
184 /*
185  *@brief
186  * Element-by-element multiply the values from three data tables and a scalar.
187  *
188  * out += in1 * in2 * in3 * scale
189  */
190 BN_EXPORT extern void bn_tabdata_incr_mul3_scale(struct bn_tabdata *out,
191  const struct bn_tabdata *in1,
192  const struct bn_tabdata *in2,
193  const struct bn_tabdata *in3,
194  double scale);
195 
196 /*
197  *@brief
198  * Element-by-element multiply the values from two data tables and a scalar.
199  *
200  * out += in1 * in2 * scale
201  */
202 BN_EXPORT extern void bn_tabdata_incr_mul2_scale(struct bn_tabdata *out,
203  const struct bn_tabdata *in1,
204  const struct bn_tabdata *in2,
205  double scale);
206 
207 /*
208  *@brief
209  * Multiply every element in a data table by a scalar value 'scale'.
210  */
211 BN_EXPORT extern void bn_tabdata_scale(struct bn_tabdata *out,
212  const struct bn_tabdata *in1,
213  double scale);
214 
215 /*
216  *@brief
217  * Scale the independent axis of a table by 'scale'.
218  */
219 BN_EXPORT extern void bn_table_scale(struct bn_table *tabp,
220  double scale);
221 
222 /*
223  *@brief
224  * Multiply every element in data table in2 by a scalar value 'scale',
225  * add it to the element in in1, and store in 'out'.
226  * 'out' may overlap in1 or in2.
227  */
228 BN_EXPORT extern void bn_tabdata_join1(struct bn_tabdata *out,
229  const struct bn_tabdata *in1,
230  double scale,
231  const struct bn_tabdata *in2);
232 
233 /*
234  *@brief
235  * Multiply every element in data table in2 by a scalar value 'scale2',
236  * plus in3 * scale3, and
237  * add it to the element in in1, and store in 'out'.
238  * 'out' may overlap in1 or in2.
239  */
240 BN_EXPORT extern void bn_tabdata_join2(struct bn_tabdata *out,
241  const struct bn_tabdata *in1,
242  double scale2,
243  const struct bn_tabdata *in2,
244  double scale3,
245  const struct bn_tabdata *in3);
246 
247 BN_EXPORT extern void bn_tabdata_blend2(struct bn_tabdata *out,
248  double scale1,
249  const struct bn_tabdata *in1,
250  double scale2,
251  const struct bn_tabdata *in2);
252 
253 BN_EXPORT extern void bn_tabdata_blend3(struct bn_tabdata *out,
254  double scale1,
255  const struct bn_tabdata *in1,
256  double scale2,
257  const struct bn_tabdata *in2,
258  double scale3,
259  const struct bn_tabdata *in3);
260 
261 /*
262  *@brief
263  * Following interpretation #1, where y[j] stores the total (integral
264  * or area) value within the interval, return the area under the whole curve.
265  * This is simply totaling up the areas from each of the intervals.
266  */
267 BN_EXPORT extern double bn_tabdata_area1(const struct bn_tabdata *in);
268 
269 /*
270  *@brief
271  * Following interpretation #2, where y[j] stores the average
272  * value for the interval, return the area under
273  * the whole curve. Since the interval spacing need not be uniform,
274  * sum the areas of the rectangles.
275  */
276 BN_EXPORT extern double bn_tabdata_area2(const struct bn_tabdata *in);
277 
278 /*
279  *@brief
280  * Following interpretation #1, where y[j] stores the total (integral
281  * or area) value within the interval, return the area under the whole curve.
282  * This is simply totaling up the areas from each of the intervals.
283  * The curve value is found by multiplying corresponding entries from
284  * in1 and in2.
285  */
286 BN_EXPORT extern double bn_tabdata_mul_area1(const struct bn_tabdata *in1,
287  const struct bn_tabdata *in2);
288 
289 /*
290  *@brief
291  * Following interpretation #2,
292  * return the area under the whole curve.
293  * The curve value is found by multiplying corresponding entries from
294  * in1 and in2.
295  */
296 BN_EXPORT extern double bn_tabdata_mul_area2(const struct bn_tabdata *in1,
297  const struct bn_tabdata *in2);
298 
299 /*
300  *@brief
301  * Return the value of the curve at independent parameter value 'wl'.
302  * Linearly interpolate between values in the input table.
303  * Zero is returned for values outside the sampled range.
304  */
305 BN_EXPORT extern fastf_t bn_table_lin_interp(const struct bn_tabdata *samp,
306  double wl);
307 
308 /*
309  *@brief
310  * Given a set of sampled data 'olddata', resample it for different
311  * spacing, by linearly interpolating the values when an output span
312  * is entirely contained within an input span, and by taking the
313  * maximum when an output span covers more than one input span.
314  *
315  * This assumes interpretation (2) of the data, i.e. that the values
316  * are the average value across the interval.
317  */
318 BN_EXPORT extern struct bn_tabdata *bn_tabdata_resample_max(const struct bn_table *newtable,
319  const struct bn_tabdata *olddata);
320 
321 /*
322  *@brief
323  * Given a set of sampled data 'olddata', resample it for different
324  * spacing, by linearly interpolating the values when an output span
325  * is entirely contained within an input span, and by taking the
326  * average when an output span covers more than one input span.
327  *
328  * This assumes interpretation (2) of the data, i.e. that the values
329  * are the average value across the interval.
330  */
331 BN_EXPORT extern struct bn_tabdata *bn_tabdata_resample_avg(const struct bn_table *newtable,
332  const struct bn_tabdata *olddata);
333 
334 /*
335  *@brief
336  * Write out the table structure in an ASCII file,
337  * giving the number of values (minus 1), and the
338  * actual values.
339  */
340 BN_EXPORT extern int bn_table_write(const char *filename,
341  const struct bn_table *tabp);
342 
343 /*
344  *@brief
345  * Allocate and read in the independent variable values from an ASCII file,
346  * giving the number of samples (minus 1), and the
347  * actual values.
348  */
349 BN_EXPORT extern struct bn_table *bn_table_read(const char *filename);
350 
351 BN_EXPORT extern void bn_pr_table(const char *title,
352  const struct bn_table *tabp);
353 
354 BN_EXPORT extern void bn_pr_tabdata(const char *title,
355  const struct bn_tabdata *data);
356 
357 /*
358  *@brief
359  * Write out a given data table into an ASCII file,
360  * suitable for input to GNUPLOT.
361  *
362  * (set term postscript)
363  * (set output "|print-postscript")
364  * (plot "filename" with lines)
365  */
366 BN_EXPORT extern int bn_print_table_and_tabdata(const char *filename,
367  const struct bn_tabdata *data);
368 
369 /*
370  *@brief
371  * Read in a file which contains two columns of numbers, the first
372  * column being the wavelength, the second column being the sample value
373  * at that wavelength.
374  *
375  * A new bn_table structure and one bn_tabdata structure
376  * are created, a pointer to the bn_tabdata structure is returned.
377  * The final wavelength is guessed at.
378  */
379 BN_EXPORT extern struct bn_tabdata *bn_read_table_and_tabdata(const char *filename);
380 
381 BN_EXPORT extern struct bn_tabdata *bn_tabdata_binary_read(const char *filename,
382  size_t num,
383  const struct bn_table *tabp);
384 
385 /*
386  *@brief
387  * Allocate storage for, and initialize, an array of 'num' data table
388  * structures.
389  * This subroutine is provided because the bn_tabdata structures
390  * are variable length.
391  */
392 BN_EXPORT extern struct bn_tabdata *bn_tabdata_malloc_array(const struct bn_table *tabp,
393  size_t num);
394 
395 BN_EXPORT extern void bn_tabdata_copy(struct bn_tabdata *out,
396  const struct bn_tabdata *in);
397 
398 BN_EXPORT extern struct bn_tabdata *bn_tabdata_dup(const struct bn_tabdata *in);
399 
400 /*
401  *@brief
402  * For a given table, allocate and return a tabdata structure
403  * with all elements initialized to 'val'.
404  */
405 BN_EXPORT extern struct bn_tabdata *bn_tabdata_get_constval(double val,
406  const struct bn_table *tabp);
407 
408 /*
409  *@brief
410  * Set all the tabdata elements to 'val'
411  */
412 BN_EXPORT extern void bn_tabdata_constval(struct bn_tabdata *data,
413  double val);
414 
415 /*
416  *@brief
417  * Convert an bn_tabdata/bn_table pair into a Tcl compatible string
418  * appended to a VLS. It will have form:
419  * x {...} y {...} nx # ymin # ymax #
420  */
421 BN_EXPORT extern void bn_tabdata_to_tcl(struct bu_vls *vp,
422  const struct bn_tabdata *data);
423 
424 /*
425  *@brief
426  * Given an array of (x, y) pairs, build the relevant bn_table and
427  * bn_tabdata structures.
428  *
429  * The table is terminated by an x value <= 0.
430  * Consistent with the interpretation of the spans,
431  * invent a final span ending x value.
432  */
433 BN_EXPORT extern struct bn_tabdata *bn_tabdata_from_array(const double *array);
434 
435 /*
436  *@brief
437  * Shift the data by a constant offset in the independent variable
438  * (often frequency), interpolating new sample values.
439  */
440 BN_EXPORT extern void bn_tabdata_freq_shift(struct bn_tabdata *out,
441  const struct bn_tabdata *in,
442  double offset);
443 
444 /*
445  *@brief
446  * Returns number of sample points between 'low' and 'hi', inclusive.
447  */
448 BN_EXPORT extern size_t bn_table_interval_num_samples(const struct bn_table *tabp,
449  double low,
450  double hi);
451 
452 /*
453  *@brief
454  * Remove all sampling points between subscripts i and j, inclusive.
455  * Don't bother freeing the tiny bit of storage at the end of the array.
456  * Returns number of points removed.
457  */
458 BN_EXPORT extern size_t bn_table_delete_sample_pnts(struct bn_table *tabp,
459  size_t i,
460  size_t j);
461 
462 /*
463  *@brief
464  * A new table is returned which has sample points at places from
465  * each of the input tables.
466  */
467 BN_EXPORT extern struct bn_table *bn_table_merge2(const struct bn_table *a,
468  const struct bn_table *b);
469 
470 /*
471  *@brief
472  * Create a filter to accept power in a given band.
473  * The first and last filter values will be in the range 0..1,
474  * while all the internal filter values will be 1.0,
475  * and all samples outside the given band will be 0.0.
476  *
477  *
478  * @return NULL if given band does not overlap input spectrum
479  * @return tabdata*
480  */
481 BN_EXPORT extern struct bn_tabdata *bn_tabdata_mk_linear_filter(const struct bn_table *spectrum,
482  double lower_wavelen,
483  double upper_wavelen);
484 
485 __END_DECLS
486 
487 #endif /* BN_TABDATA_H */
488 /** @} */
489 /*
490  * Local Variables:
491  * mode: C
492  * tab-width: 8
493  * indent-tabs-mode: t
494  * c-file-style: "stroustrup"
495  * End:
496  * ex: shiftwidth=4 tabstop=8
497  */
Header file for the BRL-CAD common definitions.
struct bn_table * bn_table_read(const char *filename)
void bn_tabdata_freq_shift(struct bn_tabdata *out, const struct bn_tabdata *in, double offset)
struct bn_table * bn_table_make_uniform(size_t num, double first, double last)
void bn_tabdata_free(struct bn_tabdata *data)
size_t bn_table_interval_num_samples(const struct bn_table *tabp, double low, double hi)
void bn_tabdata_blend3(struct bn_tabdata *out, double scale1, const struct bn_tabdata *in1, double scale2, const struct bn_tabdata *in2, double scale3, const struct bn_tabdata *in3)
void bn_tabdata_copy(struct bn_tabdata *out, const struct bn_tabdata *in)
int bn_table_write(const char *filename, const struct bn_table *tabp)
void bn_tabdata_mul(struct bn_tabdata *out, const struct bn_tabdata *in1, const struct bn_tabdata *in2)
double bn_tabdata_area1(const struct bn_tabdata *in)
struct bn_table * bn_table_merge2(const struct bn_table *a, const struct bn_table *b)
void bn_tabdata_to_tcl(struct bu_vls *vp, const struct bn_tabdata *data)
void bn_tabdata_mul3(struct bn_tabdata *out, const struct bn_tabdata *in1, const struct bn_tabdata *in2, const struct bn_tabdata *in3)
void bn_table_free(struct bn_table *tabp)
void bn_ck_table(const struct bn_table *tabp)
double bn_tabdata_area2(const struct bn_tabdata *in)
struct bn_tabdata * bn_tabdata_malloc_array(const struct bn_table *tabp, size_t num)
struct bn_tabdata * bn_tabdata_dup(const struct bn_tabdata *in)
struct bn_tabdata * bn_tabdata_get_constval(double val, const struct bn_table *tabp)
struct bn_tabdata * bn_tabdata_binary_read(const char *filename, size_t num, const struct bn_table *tabp)
void bn_tabdata_blend2(struct bn_tabdata *out, double scale1, const struct bn_tabdata *in1, double scale2, const struct bn_tabdata *in2)
size_t bn_table_delete_sample_pnts(struct bn_table *tabp, size_t i, size_t j)
struct bn_tabdata * bn_tabdata_from_array(const double *array)
struct bn_tabdata * bn_tabdata_resample_avg(const struct bn_table *newtable, const struct bn_tabdata *olddata)
void bn_tabdata_incr_mul2_scale(struct bn_tabdata *out, const struct bn_tabdata *in1, const struct bn_tabdata *in2, double scale)
void bn_tabdata_add(struct bn_tabdata *out, const struct bn_tabdata *in1, const struct bn_tabdata *in2)
void bn_tabdata_scale(struct bn_tabdata *out, const struct bn_tabdata *in1, double scale)
void bn_pr_table(const char *title, const struct bn_table *tabp)
fastf_t bn_table_lin_interp(const struct bn_tabdata *samp, double wl)
struct bn_tabdata * bn_tabdata_resample_max(const struct bn_table *newtable, const struct bn_tabdata *olddata)
void bn_tabdata_incr_mul3_scale(struct bn_tabdata *out, const struct bn_tabdata *in1, const struct bn_tabdata *in2, const struct bn_tabdata *in3, double scale)
void bn_pr_tabdata(const char *title, const struct bn_tabdata *data)
void bn_table_scale(struct bn_table *tabp, double scale)
struct bn_tabdata * bn_tabdata_mk_linear_filter(const struct bn_table *spectrum, double lower_wavelen, double upper_wavelen)
double bn_tabdata_mul_area2(const struct bn_tabdata *in1, const struct bn_tabdata *in2)
double bn_tabdata_mul_area1(const struct bn_tabdata *in1, const struct bn_tabdata *in2)
void bn_tabdata_join2(struct bn_tabdata *out, const struct bn_tabdata *in1, double scale2, const struct bn_tabdata *in2, double scale3, const struct bn_tabdata *in3)
void bn_tabdata_constval(struct bn_tabdata *data, double val)
int bn_print_table_and_tabdata(const char *filename, const struct bn_tabdata *data)
struct bn_tabdata * bn_read_table_and_tabdata(const char *filename)
void bn_tabdata_join1(struct bn_tabdata *out, const struct bn_tabdata *in1, double scale, const struct bn_tabdata *in2)
void int float float float * scale
Definition: tig.h:142
double fastf_t
fastest 64-bit (or larger) floating point type
Definition: vmath.h:334
Global registry of recognized magic numbers.
fastf_t y[1]
array of ny samples, dynamically sized
Definition: tabdata.h:121
uint32_t magic
Definition: tabdata.h:118
const struct bn_table * table
Up pointer to definition of X axis.
Definition: tabdata.h:120
size_t ny
Definition: tabdata.h:119
uint32_t magic
Definition: tabdata.h:91
size_t nx
Definition: tabdata.h:92
fastf_t x[1]
array of nx+1 wavelengths, dynamically sized
Definition: tabdata.h:93
Definition: vls.h:53
fundamental vector, matrix, quaternion math macros