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-2023 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
90struct 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
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
144BN_EXPORT extern void bn_table_free(struct bn_table *tabp);
145
146BN_EXPORT extern void bn_tabdata_free(struct bn_tabdata *data);
147
148BN_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 */
155BN_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 */
163BN_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 */
171BN_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 */
179BN_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 */
190BN_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 */
202BN_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 */
211BN_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 */
219BN_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 */
228BN_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 */
240BN_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
247BN_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
253BN_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 */
267BN_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 */
276BN_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 */
286BN_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 */
296BN_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 */
305BN_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 */
318BN_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 */
331BN_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 */
340BN_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 */
349BN_EXPORT extern struct bn_table *bn_table_read(const char *filename);
350
351BN_EXPORT extern void bn_pr_table(const char *title,
352 const struct bn_table *tabp);
353
354BN_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 */
366BN_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 */
379BN_EXPORT extern struct bn_tabdata *bn_read_table_and_tabdata(const char *filename);
380
381BN_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 */
392BN_EXPORT extern struct bn_tabdata *bn_tabdata_malloc_array(const struct bn_table *tabp,
393 size_t num);
394
395BN_EXPORT extern void bn_tabdata_copy(struct bn_tabdata *out,
396 const struct bn_tabdata *in);
397
398BN_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 */
405BN_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 */
412BN_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 */
421BN_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 */
433BN_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 */
440BN_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 */
448BN_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 */
458BN_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 */
467BN_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 */
481BN_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.
void bn_tabdata_freq_shift(struct bn_tabdata *out, const struct bn_tabdata *in, double offset)
void bn_tabdata_free(struct bn_tabdata *data)
size_t bn_table_interval_num_samples(const struct bn_table *tabp, double low, double hi)
struct bn_tabdata * bn_tabdata_malloc_array(const struct bn_table *tabp, size_t num)
struct bn_tabdata * bn_read_table_and_tabdata(const char *filename)
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)
struct bn_tabdata * bn_tabdata_dup(const struct bn_tabdata *in)
struct bn_table * bn_table_merge2(const struct bn_table *a, const struct bn_table *b)
struct bn_tabdata * bn_tabdata_resample_max(const struct bn_table *newtable, const struct bn_tabdata *olddata)
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_tabdata * bn_tabdata_binary_read(const char *filename, size_t num, const struct bn_table *tabp)
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_table * bn_table_read(const char *filename)
struct bn_tabdata * bn_tabdata_resample_avg(const struct bn_table *newtable, const struct bn_tabdata *olddata)
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)
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)
struct bn_tabdata * bn_tabdata_mk_linear_filter(const struct bn_table *spectrum, double lower_wavelen, double upper_wavelen)
fastf_t bn_table_lin_interp(const struct bn_tabdata *samp, double wl)
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_from_array(const double *array)
double bn_tabdata_mul_area2(const struct bn_tabdata *in1, const struct bn_tabdata *in2)
struct bn_tabdata * bn_tabdata_get_constval(double val, const struct bn_table *tabp)
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_table * bn_table_make_uniform(size_t num, double first, double last)
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:330
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