BRL-CAD
Loading...
Searching...
No Matches
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-2026 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/exit.h"
86#include "bu/magic.h"
87#include "bu/malloc.h"
88#include "bu/vls.h"
89
91
92struct bn_table {
94 size_t nx;
95 fastf_t x[1]; /**< @brief array of nx+1 wavelengths, dynamically sized */
96};
97
98#define BN_CK_TABLE(_p) BU_CKMAG(_p, BN_TABLE_MAGIC, "bn_table")
99#define BN_TABLE_NULL ((struct bn_table *)NULL)
100
101/* Gets an bn_table, with x[] having size _nx+1 */
102#ifndef NO_BOMBING_MACROS
103# define BN_GET_TABLE(_table, _nx) { \
104 if ((_nx) < 1) bu_bomb("RT_GET_TABLE() _nx < 1\n"); \
105 _table = (struct bn_table *)bu_calloc(1, \
106 sizeof(struct bn_table) + sizeof(fastf_t)*(_nx), \
107 "struct bn_table"); \
108 _table->magic = BN_TABLE_MAGIC; \
109 _table->nx = (_nx); }
110#else
111# define BN_GET_TABLE(_table, _nx) { \
112 _table = (struct bn_table *)bu_calloc(1, \
113 sizeof(struct bn_table) + sizeof(fastf_t)*(_nx), \
114 "struct bn_table"); \
115 _table->magic = BN_TABLE_MAGIC; \
116 _table->nx = (_nx); }
117#endif
118
121 size_t ny;
122 const struct bn_table *table; /**< @brief Up pointer to definition of X axis */
123 fastf_t y[1]; /**< @brief array of ny samples, dynamically sized */
124};
125#define BN_CK_TABDATA(_p) BU_CKMAG(_p, BN_TABDATA_MAGIC, "bn_tabdata")
126#define BN_TABDATA_NULL ((struct bn_tabdata *)NULL)
127
128#define BN_SIZEOF_TABDATA_Y(_tabdata) sizeof(fastf_t)*((_tabdata)->ny)
129#define BN_SIZEOF_TABDATA(_table) (sizeof(struct bn_tabdata) + \
130 sizeof(fastf_t)*((_table)->nx-1))
131
132/* Gets an bn_tabdata, with y[] having size _ny */
133#define BN_GET_TABDATA(_data, _table) { \
134 BN_CK_TABLE(_table);\
135 _data = (struct bn_tabdata *)bu_calloc(1, \
136 BN_SIZEOF_TABDATA(_table), "struct bn_tabdata"); \
137 _data->magic = BN_TABDATA_MAGIC; \
138 _data->ny = (_table)->nx; \
139 _data->table = (_table); }
140
141/*
142 * Routines
143 */
144
145
147
148BN_EXPORT extern void bn_tabdata_free(struct bn_tabdata *data);
149
150BN_EXPORT extern void bn_ck_table(const struct bn_table *tabp);
151
152/*
153 *@brief
154 * Set up an independent "table margin" from 'first' to 'last',
155 * inclusive, using 'num' uniformly spaced samples. Num >= 1.
156 */
158 double first,
159 double last);
160
161/*
162 *@brief
163 * Sum the values from two data tables.
164 */
165BN_EXPORT extern void bn_tabdata_add(struct bn_tabdata *out,
166 const struct bn_tabdata *in1,
167 const struct bn_tabdata *in2);
168
169/*
170 *@brief
171 * Element-by-element multiply the values from two data tables.
172 */
173BN_EXPORT extern void bn_tabdata_mul(struct bn_tabdata *out,
174 const struct bn_tabdata *in1,
175 const struct bn_tabdata *in2);
176
177/*
178 *@brief
179 * Element-by-element multiply the values from three data tables.
180 */
181BN_EXPORT extern void bn_tabdata_mul3(struct bn_tabdata *out,
182 const struct bn_tabdata *in1,
183 const struct bn_tabdata *in2,
184 const struct bn_tabdata *in3);
185
186/*
187 *@brief
188 * Element-by-element multiply the values from three data tables and a scalar.
189 *
190 * out += in1 * in2 * in3 * scale
191 */
193 const struct bn_tabdata *in1,
194 const struct bn_tabdata *in2,
195 const struct bn_tabdata *in3,
196 double scale);
197
198/*
199 *@brief
200 * Element-by-element multiply the values from two data tables and a scalar.
201 *
202 * out += in1 * in2 * scale
203 */
205 const struct bn_tabdata *in1,
206 const struct bn_tabdata *in2,
207 double scale);
208
209/*
210 *@brief
211 * Multiply every element in a data table by a scalar value 'scale'.
212 */
213BN_EXPORT extern void bn_tabdata_scale(struct bn_tabdata *out,
214 const struct bn_tabdata *in1,
215 double scale);
216
217/*
218 *@brief
219 * Scale the independent axis of a table by 'scale'.
220 */
222 double scale);
223
224/*
225 *@brief
226 * Multiply every element in data table in2 by a scalar value 'scale',
227 * add it to the element in in1, and store in 'out'.
228 * 'out' may overlap in1 or in2.
229 */
230BN_EXPORT extern void bn_tabdata_join1(struct bn_tabdata *out,
231 const struct bn_tabdata *in1,
232 double scale,
233 const struct bn_tabdata *in2);
234
235/*
236 *@brief
237 * Multiply every element in data table in2 by a scalar value 'scale2',
238 * plus in3 * scale3, and
239 * add it to the element in in1, and store in 'out'.
240 * 'out' may overlap in1 or in2.
241 */
242BN_EXPORT extern void bn_tabdata_join2(struct bn_tabdata *out,
243 const struct bn_tabdata *in1,
244 double scale2,
245 const struct bn_tabdata *in2,
246 double scale3,
247 const struct bn_tabdata *in3);
248
249BN_EXPORT extern void bn_tabdata_blend2(struct bn_tabdata *out,
250 double scale1,
251 const struct bn_tabdata *in1,
252 double scale2,
253 const struct bn_tabdata *in2);
254
255BN_EXPORT extern void bn_tabdata_blend3(struct bn_tabdata *out,
256 double scale1,
257 const struct bn_tabdata *in1,
258 double scale2,
259 const struct bn_tabdata *in2,
260 double scale3,
261 const struct bn_tabdata *in3);
262
263/*
264 *@brief
265 * Following interpretation #1, where y[j] stores the total (integral
266 * or area) value within the interval, return the area under the whole curve.
267 * This is simply totaling up the areas from each of the intervals.
268 */
269BN_EXPORT extern double bn_tabdata_area1(const struct bn_tabdata *in);
270
271/*
272 *@brief
273 * Following interpretation #2, where y[j] stores the average
274 * value for the interval, return the area under
275 * the whole curve. Since the interval spacing need not be uniform,
276 * sum the areas of the rectangles.
277 */
278BN_EXPORT extern double bn_tabdata_area2(const struct bn_tabdata *in);
279
280/*
281 *@brief
282 * Following interpretation #1, where y[j] stores the total (integral
283 * or area) value within the interval, return the area under the whole curve.
284 * This is simply totaling up the areas from each of the intervals.
285 * The curve value is found by multiplying corresponding entries from
286 * in1 and in2.
287 */
288BN_EXPORT extern double bn_tabdata_mul_area1(const struct bn_tabdata *in1,
289 const struct bn_tabdata *in2);
290
291/*
292 *@brief
293 * Following interpretation #2,
294 * return the area under the whole curve.
295 * The curve value is found by multiplying corresponding entries from
296 * in1 and in2.
297 */
298BN_EXPORT extern double bn_tabdata_mul_area2(const struct bn_tabdata *in1,
299 const struct bn_tabdata *in2);
300
301/*
302 *@brief
303 * Return the value of the curve at independent parameter value 'wl'.
304 * Linearly interpolate between values in the input table.
305 * Zero is returned for values outside the sampled range.
306 */
308 double wl);
309
310/*
311 *@brief
312 * Given a set of sampled data 'olddata', resample it for different
313 * spacing, by linearly interpolating the values when an output span
314 * is entirely contained within an input span, and by taking the
315 * maximum when an output span covers more than one input span.
316 *
317 * This assumes interpretation (2) of the data, i.e. that the values
318 * are the average value across the interval.
319 */
321 const struct bn_tabdata *olddata);
322
323/*
324 *@brief
325 * Given a set of sampled data 'olddata', resample it for different
326 * spacing, by linearly interpolating the values when an output span
327 * is entirely contained within an input span, and by taking the
328 * average when an output span covers more than one input span.
329 *
330 * This assumes interpretation (2) of the data, i.e. that the values
331 * are the average value across the interval.
332 */
334 const struct bn_tabdata *olddata);
335
336/*
337 *@brief
338 * Write out the table structure in an ASCII file,
339 * giving the number of values (minus 1), and the
340 * actual values.
341 */
342BN_EXPORT extern int bn_table_write(const char *filename,
343 const struct bn_table *tabp);
344
345/*
346 *@brief
347 * Allocate and read in the independent variable values from an ASCII file,
348 * giving the number of samples (minus 1), and the
349 * actual values.
350 */
351BN_EXPORT extern struct bn_table *bn_table_read(const char *filename);
352
353BN_EXPORT extern void bn_pr_table(const char *title,
354 const struct bn_table *tabp);
355
356BN_EXPORT extern void bn_pr_tabdata(const char *title,
357 const struct bn_tabdata *data);
358
359/*
360 *@brief
361 * Write out a given data table into an ASCII file,
362 * suitable for input to GNUPLOT.
363 *
364 * (set term postscript)
365 * (set output "|print-postscript")
366 * (plot "filename" with lines)
367 */
368BN_EXPORT extern int bn_print_table_and_tabdata(const char *filename,
369 const struct bn_tabdata *data);
370
371/*
372 *@brief
373 * Read in a file which contains two columns of numbers, the first
374 * column being the wavelength, the second column being the sample value
375 * at that wavelength.
376 *
377 * A new bn_table structure and one bn_tabdata structure
378 * are created, a pointer to the bn_tabdata structure is returned.
379 * The final wavelength is guessed at.
380 */
381BN_EXPORT extern struct bn_tabdata *bn_read_table_and_tabdata(const char *filename);
382
383BN_EXPORT extern struct bn_tabdata *bn_tabdata_binary_read(const char *filename,
384 size_t num,
385 const struct bn_table *tabp);
386
387/*
388 *@brief
389 * Allocate storage for, and initialize, an array of 'num' data table
390 * structures.
391 * This subroutine is provided because the bn_tabdata structures
392 * are variable length.
393 */
395 size_t num);
396
397BN_EXPORT extern void bn_tabdata_copy(struct bn_tabdata *out,
398 const struct bn_tabdata *in);
399
400BN_EXPORT extern struct bn_tabdata *bn_tabdata_dup(const struct bn_tabdata *in);
401
402/*
403 *@brief
404 * For a given table, allocate and return a tabdata structure
405 * with all elements initialized to 'val'.
406 */
408 const struct bn_table *tabp);
409
410/*
411 *@brief
412 * Set all the tabdata elements to 'val'
413 */
414BN_EXPORT extern void bn_tabdata_constval(struct bn_tabdata *data,
415 double val);
416
417/*
418 *@brief
419 * Convert an bn_tabdata/bn_table pair into a Tcl compatible string
420 * appended to a VLS. It will have form:
421 * x {...} y {...} nx # ymin # ymax #
422 */
423BN_EXPORT extern void bn_tabdata_to_tcl(struct bu_vls *vp,
424 const struct bn_tabdata *data);
425
426/*
427 *@brief
428 * Given an array of (x, y) pairs, build the relevant bn_table and
429 * bn_tabdata structures.
430 *
431 * The table is terminated by an x value <= 0.
432 * Consistent with the interpretation of the spans,
433 * invent a final span ending x value.
434 */
435BN_EXPORT extern struct bn_tabdata *bn_tabdata_from_array(const double *array);
436
437/*
438 *@brief
439 * Shift the data by a constant offset in the independent variable
440 * (often frequency), interpolating new sample values.
441 */
443 const struct bn_tabdata *in,
444 double offset);
445
446/*
447 *@brief
448 * Returns number of sample points between 'low' and 'hi', inclusive.
449 */
451 double low,
452 double hi);
453
454/*
455 *@brief
456 * Remove all sampling points between subscripts i and j, inclusive.
457 * Don't bother freeing the tiny bit of storage at the end of the array.
458 * Returns number of points removed.
459 */
461 size_t i,
462 size_t j);
463
464/*
465 *@brief
466 * A new table is returned which has sample points at places from
467 * each of the input tables.
468 */
469BN_EXPORT extern struct bn_table *bn_table_merge2(const struct bn_table *a,
470 const struct bn_table *b);
471
472/*
473 *@brief
474 * Create a filter to accept power in a given band.
475 * The first and last filter values will be in the range 0..1,
476 * while all the internal filter values will be 1.0,
477 * and all samples outside the given band will be 0.0.
478 *
479 *
480 * @return NULL if given band does not overlap input spectrum
481 * @return tabdata*
482 */
484 double lower_wavelen,
485 double upper_wavelen);
486
488
489#endif /* BN_TABDATA_H */
490/** @} */
491/*
492 * Local Variables:
493 * mode: C
494 * tab-width: 8
495 * indent-tabs-mode: t
496 * c-file-style: "stroustrup"
497 * End:
498 * ex: shiftwidth=4 tabstop=8
499 */
Definition dvec.h:74
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)
double fastf_t
fastest 64-bit (or larger) floating point type
Definition vmath.h:333
Global registry of recognized magic numbers.
fastf_t y[1]
array of ny samples, dynamically sized
Definition tabdata.h:123
uint32_t magic
Definition tabdata.h:120
const struct bn_table * table
Up pointer to definition of X axis.
Definition tabdata.h:122
size_t ny
Definition tabdata.h:121
uint32_t magic
Definition tabdata.h:93
size_t nx
Definition tabdata.h:94
fastf_t x[1]
array of nx+1 wavelengths, dynamically sized
Definition tabdata.h:95
Definition vls.h:53
fundamental vector, matrix, quaternion math macros