SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
SDDS_rpn.c
Go to the documentation of this file.
1/**
2 * @file SDDS_rpn.c
3 * @brief Implements Reverse Polish Notation (RPN) operations for SDDS datasets.
4 *
5 * This file provides functions to convert various data types to double and long double,
6 * as well as functions to compute parameters and columns using RPN expressions within
7 * SDDS datasets. It also includes functionality to filter rows based on RPN tests.
8 *
9 * @copyright
10 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
11 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
12 *
13 * @license
14 * This file is distributed under the terms of the Software License Agreement
15 * found in the file LICENSE included with this distribution.
16 *
17 * @authors
18 * M. Borland,
19 * C. Saunders,
20 * R. Soliday
21 * H. Shang
22 */
23
24#include "mdb.h"
25#include "match_string.h"
26#include "SDDS.h"
27#include "SDDS_internal.h"
28#include "rpn.h"
29
30/**
31 * @brief Converts a long double value to double.
32 *
33 * @param data Pointer to the data array.
34 * @param index Index of the element to convert.
35 * @return The converted double value.
36 */
37double SDDS_ConvertLongDoubleToDouble(void *data, int64_t index) {
38 return *((long double *)data + index);
39}
40
41/**
42 * @brief Converts a double value to double (identity function).
43 *
44 * @param data Pointer to the data array.
45 * @param index Index of the element.
46 * @return The double value.
47 */
48double SDDS_ConvertDoubleToDouble(void *data, int64_t index) {
49 return *((double *)data + index);
50}
51
52/**
53 * @brief Converts a float value to double.
54 *
55 * @param data Pointer to the data array.
56 * @param index Index of the element to convert.
57 * @return The converted double value.
58 */
59double SDDS_ConvertFloatToDouble(void *data, int64_t index) {
60 return *((float *)data + index);
61}
62
63/**
64 * @brief Converts a 64-bit integer to double.
65 *
66 * @param data Pointer to the data array.
67 * @param index Index of the element to convert.
68 * @return The converted double value.
69 */
70double SDDS_ConvertLong64ToDouble(void *data, int64_t index) {
71 return *((int64_t *)data + index);
72}
73
74/**
75 * @brief Converts an unsigned 64-bit integer to double.
76 *
77 * @param data Pointer to the data array.
78 * @param index Index of the element to convert.
79 * @return The converted double value.
80 */
81double SDDS_ConvertULong64ToDouble(void *data, int64_t index) {
82 return *((uint64_t *)data + index);
83}
84
85/**
86 * @brief Converts a 32-bit integer to double.
87 *
88 * @param data Pointer to the data array.
89 * @param index Index of the element to convert.
90 * @return The converted double value.
91 */
92double SDDS_ConvertLongToDouble(void *data, int64_t index) {
93 return *((int32_t *)data + index);
94}
95
96/**
97 * @brief Converts an unsigned 32-bit integer to double.
98 *
99 * @param data Pointer to the data array.
100 * @param index Index of the element to convert.
101 * @return The converted double value.
102 */
103double SDDS_ConvertULongToDouble(void *data, int64_t index) {
104 return *((uint32_t *)data + index);
105}
106
107/**
108 * @brief Converts a short integer to double.
109 *
110 * @param data Pointer to the data array.
111 * @param index Index of the element to convert.
112 * @return The converted double value.
113 */
114double SDDS_ConvertShortToDouble(void *data, int64_t index) {
115 return *((short *)data + index);
116}
117
118/**
119 * @brief Converts an unsigned short integer to double.
120 *
121 * @param data Pointer to the data array.
122 * @param index Index of the element to convert.
123 * @return The converted double value.
124 */
125double SDDS_ConvertUShortToDouble(void *data, int64_t index) {
126 return *((unsigned short *)data + index);
127}
128
129/**
130 * @brief Converts a string to double using atof.
131 *
132 * @param data Pointer to the data array.
133 * @param index Index of the element to convert.
134 * @return The converted double value.
135 */
136double SDDS_ConvertStringToDouble(void *data, int64_t index) {
137 return atof(*((char **)data + index));
138}
139
140/**
141 * @brief Converts a character to double.
142 *
143 * @param data Pointer to the data array.
144 * @param index Index of the element to convert.
145 * @return The converted double value.
146 */
147double SDDS_ConvertCharToDouble(void *data, int64_t index) {
148 return *((char *)data + index);
149}
150
151/**
152 * @brief Converts a value to long double based on its type.
153 *
154 * @param type The SDDS data type of the value.
155 * @param data Pointer to the data array.
156 * @param index Index of the element to convert.
157 * @return The converted long double value, or 0.0 on error.
158 */
159long double SDDS_ConvertToLongDouble(int32_t type, void *data, int64_t index) {
160 if (!data) {
161 SDDS_SetError("NULL data pointer passed (SDDS_ConvertToLongDouble)");
162 return (0.0);
163 }
164 switch (type) {
165 case SDDS_SHORT:
166 return ((long double)*((short *)data + index));
167 case SDDS_USHORT:
168 return ((long double)*((unsigned short *)data + index));
169 case SDDS_LONG:
170 return ((long double)*((int32_t *)data + index));
171 case SDDS_ULONG:
172 return ((long double)*((uint32_t *)data + index));
173 case SDDS_LONG64:
174 return ((long double)*((int64_t *)data + index));
175 case SDDS_ULONG64:
176 return ((long double)*((uint64_t *)data + index));
177 case SDDS_FLOAT:
178 return ((long double)*((float *)data + index));
179 case SDDS_DOUBLE:
180 return ((long double)*((double *)data + index));
181 case SDDS_LONGDOUBLE:
182 return (*((long double *)data + index));
183 case SDDS_CHARACTER:
184 return ((long double)*((unsigned char *)data + index));
185 default:
186 SDDS_SetError("Invalid data type seen (SDDS_ConvertToLongDouble)");
187 return (0.0);
188 }
189}
190
191/**
192 * @brief Converts a value to double based on its type.
193 *
194 * @param type The SDDS data type of the value.
195 * @param data Pointer to the data array.
196 * @param index Index of the element to convert.
197 * @return The converted double value, or 0.0 on error.
198 */
199double SDDS_ConvertToDouble(int32_t type, void *data, int64_t index) {
200 if (!data) {
201 SDDS_SetError("NULL data pointer passed (SDDS_ConvertToDouble)");
202 return (0.0);
203 }
204 switch (type) {
205 case SDDS_SHORT:
206 return ((double)*((short *)data + index));
207 case SDDS_USHORT:
208 return ((double)*((unsigned short *)data + index));
209 case SDDS_LONG:
210 return ((double)*((int32_t *)data + index));
211 case SDDS_ULONG:
212 return ((double)*((uint32_t *)data + index));
213 case SDDS_LONG64:
214 return ((double)*((int64_t *)data + index));
215 case SDDS_ULONG64:
216 return ((double)*((uint64_t *)data + index));
217 case SDDS_FLOAT:
218 return ((double)*((float *)data + index));
219 case SDDS_DOUBLE:
220 return (*((double *)data + index));
221 case SDDS_LONGDOUBLE:
222 return ((double)*((long double *)data + index));
223 case SDDS_CHARACTER:
224 return ((double)*((unsigned char *)data + index));
225 default:
226 SDDS_SetError("Invalid data type seen (SDDS_ConvertToDouble)");
227 return (0.0);
228 }
229}
230
231/**
232 * @brief Converts a value to a 64-bit integer based on its type.
233 *
234 * @param type The SDDS data type of the value.
235 * @param data Pointer to the data array.
236 * @param index Index of the element to convert.
237 * @return The converted 64-bit integer, or 0 on error.
238 */
239int64_t SDDS_ConvertToLong64(int32_t type, void *data, int64_t index) {
240 if (!data) {
241 SDDS_SetError("NULL data pointer passed (SDDS_ConvertToLong64)");
242 return (0.0);
243 }
244 switch (type) {
245 case SDDS_LONGDOUBLE:
246 return ((int64_t) * ((long double *)data + index));
247 case SDDS_DOUBLE:
248 return ((int64_t) * ((double *)data + index));
249 case SDDS_FLOAT:
250 return ((int64_t) * ((float *)data + index));
251 case SDDS_SHORT:
252 return ((int64_t) * ((short *)data + index));
253 case SDDS_USHORT:
254 return ((int64_t) * ((unsigned short *)data + index));
255 case SDDS_LONG:
256 return ((int64_t) * ((int32_t *)data + index));
257 case SDDS_ULONG:
258 return ((int64_t) * ((uint32_t *)data + index));
259 case SDDS_LONG64:
260 return (*((int64_t *)data + index));
261 case SDDS_ULONG64:
262 return ((int64_t) * ((uint64_t *)data + index));
263 case SDDS_CHARACTER:
264 return ((int64_t) * ((unsigned char *)data + index));
265 default:
266 SDDS_SetError("Invalid data type seen (SDDS_ConvertToLong64)");
267 return (0.0);
268 }
269}
270
271/**
272 * @brief Converts a value to a 32-bit integer based on its type.
273 *
274 * @param type The SDDS data type of the value.
275 * @param data Pointer to the data array.
276 * @param index Index of the element to convert.
277 * @return The converted 32-bit integer, or 0 on error.
278 */
279int32_t SDDS_ConvertToLong(int32_t type, void *data, int64_t index) {
280 if (!data) {
281 SDDS_SetError("NULL data pointer passed (SDDS_ConvertToLong)");
282 return (0.0);
283 }
284 switch (type) {
285 case SDDS_LONGDOUBLE:
286 return ((int32_t) * ((long double *)data + index));
287 case SDDS_DOUBLE:
288 return ((int32_t) * ((double *)data + index));
289 case SDDS_FLOAT:
290 return ((int32_t) * ((float *)data + index));
291 case SDDS_SHORT:
292 return ((int32_t) * ((short *)data + index));
293 case SDDS_USHORT:
294 return ((int32_t) * ((unsigned short *)data + index));
295 case SDDS_LONG:
296 return (*((int32_t *)data + index));
297 case SDDS_ULONG:
298 return ((int32_t) * ((uint32_t *)data + index));
299 case SDDS_LONG64:
300 return ((int32_t) * ((int64_t *)data + index));
301 case SDDS_ULONG64:
302 return ((int32_t) * ((uint64_t *)data + index));
303 case SDDS_CHARACTER:
304 return ((int32_t) * ((unsigned char *)data + index));
305 default:
306 SDDS_SetError("Invalid data type seen (SDDS_ConvertToLong)");
307 return (0.0);
308 }
309}
310
311#if defined(RPN_SUPPORT)
312
313static double (*const SDDS_ConvertTypeToDouble[SDDS_NUM_TYPES + 1])(void *data, int64_t index) =
314 {
315 NULL,
327
328// Static variables to store memory identifiers for RPN operations
329static MDB_THREAD_LOCAL int64_t table_number_mem = -1;
330static MDB_THREAD_LOCAL int64_t i_page_mem = -1;
331static MDB_THREAD_LOCAL int64_t n_rows_mem = -1;
332static MDB_THREAD_LOCAL int64_t i_row_mem = -1;
333
334/**
335 * @brief Creates an RPN memory block.
336 *
337 * @param name Name of the RPN memory.
338 * @param is_string Flag indicating if the memory is for string data.
339 * @return Identifier of the created RPN memory, or -1 on failure.
340 */
341int64_t SDDS_CreateRpnMemory(const char *name, short is_string) {
342 if (!name)
343 return (-1);
344 return (rpn_create_mem((char *)name, is_string));
345}
346
347/**
348 * @brief Creates an RPN array for a given name.
349 *
350 * @param name Name of the RPN array.
351 * @return Identifier of the created RPN array, or -1 on failure.
352 */
353int64_t SDDS_CreateRpnArray(char *name) {
354 int64_t memnum = -1;
355 double dummy;
356 char *dummy1 = NULL;
357 long is_string = 0;
358
359 if (!name)
360 return (-1);
361 rpn_lock();
362 if ((memnum = is_memory(&dummy, &dummy1, &is_string, name)) >= 0) {
363 rpn_unlock();
364 return memnum;
365 }
366 if ((memnum = rpn_create_mem(name, is_string)) >= 0)
367 rpn_store((double)rpn_createarray(1), NULL, memnum);
368 rpn_unlock();
369 return memnum;
370}
371
372/**
373 * @brief Computes a parameter in the SDDS dataset using an RPN equation.
374 *
375 * @param SDDS_dataset Pointer to the SDDS dataset.
376 * @param parameter Index of the parameter to compute.
377 * @param equation RPN equation as a string.
378 * @return 1 on success, 0 on failure.
379 */
380int32_t SDDS_ComputeParameter(SDDS_DATASET *SDDS_dataset, int32_t parameter, char *equation) {
381 SDDS_LAYOUT *layout;
382 double value;
383 int32_t status = 0;
384
385 rpn_lock();
386 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ComputeParameter"))
387 goto cleanup;
388 layout = &SDDS_dataset->layout;
389 if (parameter < 0 || parameter >= layout->n_parameters)
390 goto cleanup;
391
392 if (!equation) {
393 SDDS_SetError("Unable to compute defined parameter--no equation for named parameter (SDDS_ComputeParameter)");
394 goto cleanup;
395 }
396
397 if (!SDDS_StoreParametersInRpnMemories(SDDS_dataset))
398 goto cleanup;
399 if (!SDDS_StoreColumnsInRpnArrays(SDDS_dataset))
400 goto cleanup;
401
402 value = rpn(equation);
403 rpn_store(value, NULL, layout->parameter_definition[parameter].memory_number);
404 if (rpn_check_error()) {
405 SDDS_SetError("Unable to compute rpn expression--rpn error (SDDS_ComputeParameter)");
406 goto cleanup;
407 }
408# if defined(DEBUG)
409 fprintf(stderr, "computed parameter value %s with equation %s: %e\n", layout->parameter_definition[parameter].name, equation, value);
410# endif
411 switch (layout->parameter_definition[parameter].type) {
412 case SDDS_CHARACTER:
413 SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, parameter, (char)value, -1);
414 break;
415 case SDDS_SHORT:
416 SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, parameter, (short)value, -1);
417 break;
418 case SDDS_USHORT:
419 SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, parameter, (unsigned short)value, -1);
420 break;
421 case SDDS_LONG:
422 SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, parameter, (int32_t)value, -1);
423 break;
424 case SDDS_ULONG:
425 SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, parameter, (uint32_t)value, -1);
426 break;
427 case SDDS_LONG64:
428 SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, parameter, (int64_t)value, -1);
429 break;
430 case SDDS_ULONG64:
431 SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, parameter, (uint64_t)value, -1);
432 break;
433 case SDDS_FLOAT:
434 SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, parameter, (float)value, -1);
435 break;
436 case SDDS_DOUBLE:
437 SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, parameter, (double)value, -1);
438 break;
439 case SDDS_LONGDOUBLE:
440 SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, parameter, (long double)value, -1);
441 break;
442 }
443
444 status = 1;
445
446cleanup:
447 rpn_unlock();
448 return status;
449}
450
451/**
452 * @brief Computes a column in the SDDS dataset using an RPN equation.
453 *
454 * @param SDDS_dataset Pointer to the SDDS dataset.
455 * @param column Index of the column to compute.
456 * @param equation RPN equation as a string.
457 * @return 1 on success, 0 on failure.
458 */
459int32_t SDDS_ComputeColumn(SDDS_DATASET *SDDS_dataset, int32_t column, char *equation) {
460 int64_t j;
461 SDDS_LAYOUT *layout;
462 double value;
463 int32_t status = 0;
464
465 rpn_lock();
466 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ComputeColumn"))
467 goto cleanup;
468 layout = &SDDS_dataset->layout;
469 if (column < 0 || column >= layout->n_columns)
470 goto cleanup;
471
472 if (!SDDS_StoreParametersInRpnMemories(SDDS_dataset))
473 goto cleanup;
474 if (!SDDS_StoreColumnsInRpnArrays(SDDS_dataset))
475 goto cleanup;
476
477 if (table_number_mem == -1) {
478 table_number_mem = rpn_create_mem("table_number", 0);
479 i_page_mem = rpn_create_mem("i_page", 0);
480 n_rows_mem = rpn_create_mem("n_rows", 0);
481 i_row_mem = rpn_create_mem("i_row", 0);
482 }
483
484 rpn_store((double)SDDS_dataset->page_number, NULL, table_number_mem);
485 rpn_store((double)SDDS_dataset->page_number, NULL, i_page_mem);
486 rpn_store((double)SDDS_dataset->n_rows, NULL, n_rows_mem);
487# if defined(DEBUG)
488 fprintf(stderr, "computing %s using equation %s\n", layout->column_definition[column].name, equation);
489# endif
490
491 for (j = 0; j < SDDS_dataset->n_rows; j++) {
492 rpn_clear();
493 if (!SDDS_StoreRowInRpnMemories(SDDS_dataset, j))
494 goto cleanup;
495 rpn_store((double)j, NULL, i_row_mem);
496 value = rpn(equation);
497 rpn_store(value, NULL, layout->column_definition[column].memory_number);
498 if (rpn_check_error()) {
499 SDDS_SetError("Unable to compute rpn expression--rpn error (SDDS_ComputeDefinedColumn)");
500 goto cleanup;
501 }
502# if defined(DEBUG)
503 fprintf(stderr, "computed row value: %s = %e\n", layout->column_definition[column].name, value);
504# endif
505 switch (layout->column_definition[column].type) {
506 case SDDS_CHARACTER:
507 SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, j, column, (char)value, -1);
508 break;
509 case SDDS_SHORT:
510 SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, j, column, (short)value, -1);
511 break;
512 case SDDS_USHORT:
513 SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, j, column, (unsigned short)value, -1);
514 break;
515 case SDDS_LONG:
516 SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, j, column, (int32_t)value, -1);
517 break;
518 case SDDS_ULONG:
519 SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, j, column, (uint32_t)value, -1);
520 break;
521 case SDDS_LONG64:
522 SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, j, column, (int64_t)value, -1);
523 break;
524 case SDDS_ULONG64:
525 SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, j, column, (uint64_t)value, -1);
526 break;
527 case SDDS_FLOAT:
528 SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, j, column, (float)value, -1);
529 break;
530 case SDDS_DOUBLE:
531 SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, j, column, (double)value, -1);
532 break;
533 case SDDS_LONGDOUBLE:
534 SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, j, column, (long double)value, -1);
535 break;
536 }
537 }
538
539 status = 1;
540
541cleanup:
542 rpn_unlock();
543 return status;
544}
545
546/**
547 * @brief Filters rows in the SDDS dataset based on an RPN test expression.
548 *
549 * @param SDDS_dataset Pointer to the SDDS dataset.
550 * @param rpn_test RPN test expression as a string.
551 * @return 1 on success, 0 on failure.
552 */
553int32_t SDDS_FilterRowsWithRpnTest(SDDS_DATASET *SDDS_dataset, char *rpn_test) {
554 int64_t i, j;
555 int32_t n_columns;
556 SDDS_LAYOUT *layout;
557 int32_t accept;
558 static MDB_THREAD_LOCAL int64_t table_number_mem = -1, n_rows_mem = -1, i_page_mem = -1;
559 COLUMN_DEFINITION *coldef;
560 int32_t status = 0;
561
562 rpn_lock();
563 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_ComputeRpnEquations"))
564 goto cleanup;
565 layout = &SDDS_dataset->layout;
566
567 if (table_number_mem == -1) {
568 table_number_mem = rpn_create_mem("table_number", 0);
569 i_page_mem = rpn_create_mem("page_number", 0);
570 n_rows_mem = rpn_create_mem("n_rows", 0);
571 i_row_mem = rpn_create_mem("i_row", 0);
572 }
573
574 rpn_store((double)SDDS_dataset->page_number, NULL, table_number_mem);
575 rpn_store((double)SDDS_dataset->page_number, NULL, i_page_mem);
576 rpn_store((double)SDDS_dataset->n_rows, NULL, n_rows_mem);
577
578 for (i = 0; i < layout->n_columns; i++) {
579 if (layout->column_definition[i].memory_number < 0) {
580 SDDS_SetError("Unable to compute equations--column lacks rpn memory number (SDDS_FilterRowsWithRpnTest)");
581 goto cleanup;
582 }
583 }
584
585 n_columns = layout->n_columns;
586
587 for (j = 0; j < SDDS_dataset->n_rows; j++) {
588 rpn_clear();
589 rpn_store((double)j, NULL, i_row_mem);
590 /* store values in memories */
591 coldef = layout->column_definition;
592 for (i = 0; i < n_columns; i++, coldef++) {
593 if (coldef->type != SDDS_STRING) {
594 rpn_quick_store((*SDDS_ConvertTypeToDouble[coldef->type])(SDDS_dataset->data[i], j), NULL, coldef->memory_number);
595 } else {
596 rpn_quick_store(0, ((char **)SDDS_dataset->data[i])[j], coldef->memory_number);
597 }
598 }
599 rpn(rpn_test);
600 if (rpn_check_error()) {
601 SDDS_SetError("Unable to compute rpn expression--rpn error (SDDS_FilterRowsWithRpnTest)");
602 goto cleanup;
603 }
604 if (!pop_log(&accept)) {
605 SDDS_SetError("rpn column-based test expression problem");
606 goto cleanup;
607 }
608 if (!accept)
609 SDDS_dataset->row_flag[j] = 0;
610 }
611 rpn_clear();
612 status = 1;
613
614cleanup:
615 rpn_unlock();
616 return status;
617}
618
619/**
620 * @brief Stores all parameters of the SDDS dataset into RPN memories.
621 *
622 * @param SDDS_dataset Pointer to the SDDS dataset.
623 * @return 1 on success, 0 on failure.
624 */
625int32_t SDDS_StoreParametersInRpnMemories(SDDS_DATASET *SDDS_dataset) {
626 int32_t i;
627 SDDS_LAYOUT *layout;
628 int32_t status = 0;
629
630 rpn_lock();
631 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_StoreParametersInRpnMemories"))
632 goto cleanup;
633 layout = &SDDS_dataset->layout;
634
635 rpn_clear();
636# if defined(DEBUG)
637 fprintf(stderr, "storing parameters: ");
638# endif
639 for (i = 0; i < layout->n_parameters; i++) {
640 if (layout->parameter_definition[i].memory_number < 0) {
641 SDDS_SetError("Unable to compute equations--parameter lacks rpn memory number (SDDS_StoreParametersInRpnMemories");
642 goto cleanup;
643 }
644 if (layout->parameter_definition[i].type != SDDS_STRING) {
645 rpn_quick_store((*SDDS_ConvertTypeToDouble[layout->parameter_definition[i].type])(SDDS_dataset->parameter[i], 0), NULL, layout->parameter_definition[i].memory_number);
646# if defined(DEBUG)
647 fprintf(stderr, "%s = %le ", layout->parameter_definition[i].name, rpn_recall(layout->parameter_definition[i].memory_number));
648# endif
649 } else {
650 rpn_quick_store(0, ((char **)SDDS_dataset->parameter[i])[0], layout->parameter_definition[i].memory_number);
651# if defined(DEBUG)
652 fprintf(stderr, "%s = %s ", layout->parameter_definition[i].name, rpn_str_recall(layout->parameter_definition[i].memory_number));
653# endif
654 }
655 }
657 goto cleanup;
658 if (rpn_check_error()) {
659 SDDS_SetError("Unable to compute rpn expression--rpn error (SDDS_StoreParametersInRpnMemories)");
660 goto cleanup;
661 }
662# if defined(DEBUG)
663 fputc('\n', stderr);
664# endif
665 status = 1;
666
667cleanup:
668 rpn_unlock();
669 return status;
670}
671
672/**
673 * @brief Stores a specific row's column values into RPN memories.
674 *
675 * @param SDDS_dataset Pointer to the SDDS dataset.
676 * @param row Index of the row to store.
677 * @return 1 on success, 0 on failure.
678 */
679int32_t SDDS_StoreRowInRpnMemories(SDDS_DATASET *SDDS_dataset, int64_t row) {
680 int32_t i, columns;
681 COLUMN_DEFINITION *coldef;
682 int32_t status = 0;
683
684 rpn_lock();
685 columns = SDDS_dataset->layout.n_columns;
686 if (row == 0) {
687 coldef = SDDS_dataset->layout.column_definition;
688 for (i = 0; i < columns; i++, coldef++) {
689 if (coldef->memory_number < 0) {
690 SDDS_SetError("Unable to compute equations--column lacks rpn memory number (SDDS_StoreRowInRpnMemories)");
691 goto cleanup;
692 }
693 }
694 }
695 coldef = SDDS_dataset->layout.column_definition;
696 for (i = 0; i < columns; i++, coldef++) {
697 if (coldef->type != SDDS_STRING) {
698 rpn_quick_store((*SDDS_ConvertTypeToDouble[coldef->type])(SDDS_dataset->data[i], row), NULL, coldef->memory_number);
699 } else {
700 rpn_quick_store(0, ((char **)SDDS_dataset->data[i])[row], coldef->memory_number);
701 }
702 }
703 status = 1;
704
705cleanup:
706 rpn_unlock();
707 return status;
708}
709
710/**
711 * @brief Stores all column data into RPN arrays for efficient computation.
712 *
713 * @param SDDS_dataset Pointer to the SDDS dataset.
714 * @return 1 on success, 0 on failure.
715 */
716int32_t SDDS_StoreColumnsInRpnArrays(SDDS_DATASET *SDDS_dataset) {
717 int64_t i, j;
718 int32_t arraysize;
719 SDDS_LAYOUT *layout;
720 double *arraydata;
721 int32_t *longPtr;
722 uint32_t *ulongPtr;
723 int64_t *long64Ptr;
724 uint64_t *ulong64Ptr;
725 short *shortPtr;
726 unsigned short *ushortPtr;
727 long double *ldoublePtr;
728 /* double *doublePtr; */
729 float *floatPtr;
730 char *charPtr;
731 int32_t status = 0;
732
733 rpn_lock();
734 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_StoreColumnsRpnArrays"))
735 goto cleanup;
736 layout = &SDDS_dataset->layout;
737 rpn_clear();
738 for (i = 0; i < layout->n_columns; i++) {
739 if (layout->column_definition[i].type != SDDS_STRING) {
740 if (layout->column_definition[i].pointer_number < 0) {
741 SDDS_SetError("Unable to compute equations--column lacks rpn pointer number (SDDS_StoreColumnsInRpnArrays)");
742 goto cleanup;
743 }
744 if (!rpn_resizearray((int32_t)rpn_recall(layout->column_definition[i].pointer_number), SDDS_dataset->n_rows)) {
745 SDDS_SetError("Unable to compute equations--couldn't resize rpn arrays (SDDS_StoreColumnsInRpnArrays)");
746 goto cleanup;
747 }
748 if (!(arraydata = rpn_getarraypointer(layout->column_definition[i].pointer_number, &arraysize)) || arraysize != SDDS_dataset->n_rows) {
749 SDDS_SetError("Unable to compute equations--couldn't retrieve rpn arrays (SDDS_StoreColumnsInRpnArrays)");
750 goto cleanup;
751 }
752 switch (layout->column_definition[i].type) {
753 case SDDS_LONGDOUBLE:
754 ldoublePtr = (long double *)(SDDS_dataset->data[i]);
755 for (j = 0; j < SDDS_dataset->n_rows; j++)
756 arraydata[j] = ldoublePtr[j];
757 break;
758 case SDDS_DOUBLE:
759 memcpy((char *)arraydata, (char *)(SDDS_dataset->data[i]), SDDS_dataset->n_rows * sizeof(double));
760# if 0
761 doublePtr = (double *)(SDDS_dataset->data[i]);
762 for (j = 0; j < SDDS_dataset->n_rows; j++)
763 arraydata[j] = doublePtr[j];
764# endif
765 break;
766 case SDDS_FLOAT:
767 floatPtr = (float *)(SDDS_dataset->data[i]);
768 for (j = 0; j < SDDS_dataset->n_rows; j++)
769 arraydata[j] = floatPtr[j];
770 break;
771 case SDDS_LONG64:
772 long64Ptr = (int64_t *)(SDDS_dataset->data[i]);
773 for (j = 0; j < SDDS_dataset->n_rows; j++)
774 arraydata[j] = long64Ptr[j];
775 break;
776 case SDDS_ULONG64:
777 ulong64Ptr = (uint64_t *)(SDDS_dataset->data[i]);
778 for (j = 0; j < SDDS_dataset->n_rows; j++)
779 arraydata[j] = ulong64Ptr[j];
780 break;
781 case SDDS_LONG:
782 longPtr = (int32_t *)(SDDS_dataset->data[i]);
783 for (j = 0; j < SDDS_dataset->n_rows; j++)
784 arraydata[j] = longPtr[j];
785 break;
786 case SDDS_ULONG:
787 ulongPtr = (uint32_t *)(SDDS_dataset->data[i]);
788 for (j = 0; j < SDDS_dataset->n_rows; j++)
789 arraydata[j] = ulongPtr[j];
790 break;
791 case SDDS_SHORT:
792 shortPtr = (short *)(SDDS_dataset->data[i]);
793 for (j = 0; j < SDDS_dataset->n_rows; j++)
794 arraydata[j] = shortPtr[j];
795 break;
796 case SDDS_USHORT:
797 ushortPtr = (unsigned short *)(SDDS_dataset->data[i]);
798 for (j = 0; j < SDDS_dataset->n_rows; j++)
799 arraydata[j] = ushortPtr[j];
800 break;
801 case SDDS_CHARACTER:
802 charPtr = (char *)(SDDS_dataset->data[i]);
803 for (j = 0; j < SDDS_dataset->n_rows; j++)
804 arraydata[j] = charPtr[j];
805 break;
806 }
807 }
808 }
809 status = 1;
810
811cleanup:
812 rpn_unlock();
813 return status;
814}
815
816#else /* end of RPN_SUPPORT section */
817
818/**
819 * @brief Stub function for creating RPN memory when RPN_SUPPORT is not enabled.
820 *
821 * @param name Name of the RPN memory.
822 * @param is_string Flag indicating if the memory is for string data.
823 * @return Always returns 1.
824 */
825int64_t SDDS_CreateRpnMemory(const char *name, short is_string) {
826 return (1);
827}
828
829/**
830 * @brief Stub function for creating RPN arrays when RPN_SUPPORT is not enabled.
831 *
832 * @param name Name of the RPN array.
833 * @return Always returns 1.
834 */
835int64_t SDDS_CreateRpnArray(char *name) {
836 return (1);
837}
838
839#endif
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
Internal definitions and function declarations for SDDS with LZMA support.
int64_t SDDS_ConvertToLong64(int32_t type, void *data, int64_t index)
Converts a value to a 64-bit integer based on its type.
Definition SDDS_rpn.c:239
double SDDS_ConvertToDouble(int32_t type, void *data, int64_t index)
Converts a value to double based on its type.
Definition SDDS_rpn.c:199
int64_t SDDS_CreateRpnMemory(const char *name, short is_string)
Stub function for creating RPN memory when RPN_SUPPORT is not enabled.
Definition SDDS_rpn.c:825
long double SDDS_ConvertToLongDouble(int32_t type, void *data, int64_t index)
Converts a value to long double based on its type.
Definition SDDS_rpn.c:159
double SDDS_ConvertCharToDouble(void *data, int64_t index)
Converts a character to double.
Definition SDDS_rpn.c:147
double SDDS_ConvertULongToDouble(void *data, int64_t index)
Converts an unsigned 32-bit integer to double.
Definition SDDS_rpn.c:103
double SDDS_ConvertFloatToDouble(void *data, int64_t index)
Converts a float value to double.
Definition SDDS_rpn.c:59
double SDDS_ConvertLong64ToDouble(void *data, int64_t index)
Converts a 64-bit integer to double.
Definition SDDS_rpn.c:70
double SDDS_ConvertDoubleToDouble(void *data, int64_t index)
Converts a double value to double (identity function).
Definition SDDS_rpn.c:48
double SDDS_ConvertShortToDouble(void *data, int64_t index)
Converts a short integer to double.
Definition SDDS_rpn.c:114
double SDDS_ConvertLongToDouble(void *data, int64_t index)
Converts a 32-bit integer to double.
Definition SDDS_rpn.c:92
double SDDS_ConvertUShortToDouble(void *data, int64_t index)
Converts an unsigned short integer to double.
Definition SDDS_rpn.c:125
int64_t SDDS_CreateRpnArray(char *name)
Stub function for creating RPN arrays when RPN_SUPPORT is not enabled.
Definition SDDS_rpn.c:835
int32_t SDDS_ConvertToLong(int32_t type, void *data, int64_t index)
Converts a value to a 32-bit integer based on its type.
Definition SDDS_rpn.c:279
double SDDS_ConvertStringToDouble(void *data, int64_t index)
Converts a string to double using atof.
Definition SDDS_rpn.c:136
double SDDS_ConvertULong64ToDouble(void *data, int64_t index)
Converts an unsigned 64-bit integer to double.
Definition SDDS_rpn.c:81
double SDDS_ConvertLongDoubleToDouble(void *data, int64_t index)
Converts a long double value to double.
Definition SDDS_rpn.c:37
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:421
int32_t SDDS_CheckDataset(SDDS_DATASET *SDDS_dataset, const char *caller)
Validates the SDDS dataset pointer.
Definition SDDS_utils.c:618
int32_t SDDS_NumberOfErrors()
Retrieves the number of errors recorded by SDDS library routines.
Definition SDDS_utils.c:340
#define SDDS_NUM_TYPES
Total number of defined SDDS data types.
Definition SDDStypes.h:97
#define SDDS_ULONG
Identifier for the unsigned 32-bit integer data type.
Definition SDDStypes.h:67
#define SDDS_FLOAT
Identifier for the float data type.
Definition SDDStypes.h:43
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_ULONG64
Identifier for the unsigned 64-bit integer data type.
Definition SDDStypes.h:55
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_SHORT
Identifier for the signed short integer data type.
Definition SDDStypes.h:73
#define SDDS_CHARACTER
Identifier for the character data type.
Definition SDDStypes.h:91
#define SDDS_USHORT
Identifier for the unsigned short integer data type.
Definition SDDStypes.h:79
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
#define SDDS_LONGDOUBLE
Identifier for the long double data type.
Definition SDDStypes.h:31
#define SDDS_LONG64
Identifier for the signed 64-bit integer data type.
Definition SDDStypes.h:49