SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
sddssort.c
Go to the documentation of this file.
1/**
2 * @file sddssort.c
3 * @brief Sorts an SDDS dataset by column or parameter values.
4 *
5 * @details
6 * The `sddssort` program provides flexible sorting capabilities for SDDS datasets. Users can sort by one or more
7 * columns or parameters, perform unique row elimination, and handle multi-criteria optimization through
8 * non-dominated sorting. The program supports numeric sorting, absolute value sorting, and major order changes
9 * for row or column storage.
10 *
11 * @section Usage
12 * ```
13 * sddssort [<inputfile>] [<outputfile>]
14 * [-pipe=[input][,output]]
15 * [-column=<name>[,{increasing|decreasing}|{minimize|maximize}][,absolute]...]
16 * [-unique[=count]]
17 * [-nowarnings]
18 * [-parameter=<name>[,{increasing|decreasing}]...]
19 * [-numericHigh]
20 * [-nonDominateSort]
21 * [-majorOrder=row|column]
22 * ```
23 *
24 * @section Options
25 * | Optional | Description |
26 * |---------------------------------------|---------------------------------------------------------------------------------------|
27 * | `-pipe` | Enables piping for input and/or output. |
28 * | `-column` | Specifies columns for sorting with optional modifiers. |
29 * | `-unique` | Removes duplicate rows. If `count` is specified, includes an `IdenticalCount` column. |
30 * | `-nowarnings` | Suppresses warning messages. |
31 * | `-parameter` | Specifies parameters for sorting with optional modifiers. |
32 * | `-numericHigh` | Prioritizes numeric characters in string comparisons. |
33 * | `-nonDominateSort` | Enables non-dominated sorting for numeric columns. |
34 * | `-majorOrder` | Changes the data storage order to row-major or column-major. |
35 *
36 * @subsection spec_req Specific Requirements
37 * - For `-nonDominateSort`:
38 * - Requires at least two columns.
39 * - Columns must contain numeric data types.
40 *
41 * @copyright
42 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
43 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
44 *
45 * @license
46 * This file is distributed under the terms of the Software License Agreement
47 * found in the file LICENSE included with this distribution.
48 *
49 * @author
50 * M. Borland, C. Saunders, R. Soliday, H. Shang
51 */
52
53#include "mdb.h"
54#include "SDDS.h"
55#include "scan.h"
56#include "non_dominated_sort.h"
57#if defined(_WIN32)
58# include <process.h>
59# define pid_t int
60#else
61# if defined(linux)
62# include <sys/types.h>
63# endif
64# include <unistd.h>
65#endif
66
67/* Enumeration for option types */
68enum option_type {
69 SET_COLUMN,
70 SET_PARAMETER,
71 SET_NOWARNINGS,
72 SET_PIPE,
73 SET_UNIQUE,
74 SET_NUMERICHIGH,
75 SET_NON_DOMINATE_SORT,
76 SET_MAJOR_ORDER,
77 SET_HYPERVOLUME,
78 N_OPTIONS
79};
80
81char *option[N_OPTIONS] = {
82 "column",
83 "parameter",
84 "nowarnings",
85 "pipe",
86 "unique",
87 "numerichigh",
88 "nonDominateSort",
89 "majorOrder",
90 "hypervolume",
91};
92
93/* Improved Usage Message */
94char *USAGE =
95 "sddssort [<SDDSinput>] [<SDDSoutput>]\n"
96 " [-pipe=[input][,output]]\n"
97 " [-column=<name>[,{increasing|decreasing}|{minimize|maximize}][,absolute]...] \n"
98 " [-unique[=count]]\n"
99 " [-nowarnings] \n"
100 " [-parameter=<name>[,{increasing|decreasing}]...]\n"
101 " [-numericHigh] \n"
102 " [-nonDominateSort] \n"
103 " [-hypervolume=<ref1>,<ref2>,...] \n"
104 " [-majorOrder=row|column]\n"
105 "Options:\n"
106 " -pipe=[input][,output]\n"
107 " Enable piping for input and/or output.\n\n"
108 " -column=<name>[,{increasing|decreasing}|{minimize|maximize}][,absolute]...\n"
109 " Specify one or more columns to sort by.\n"
110 " - 'increasing' or 'decreasing' sets the sorting direction for regular sorting.\n"
111 " - 'minimize' or 'maximize' sets the sorting direction for non-dominated sorting.\n"
112 " - 'absolute' sorts based on absolute values.\n\n"
113 " -unique[=count]\n"
114 " Eliminate duplicate rows based on sort columns.\n"
115 " If 'count' is specified, an 'IdenticalCount' column is added to indicate the number of identical rows.\n\n"
116 " -nowarnings\n"
117 " Suppress warning messages.\n\n"
118 " -parameter=<name>[,{increasing|decreasing}]...\n"
119 " Specify parameters to sort by.\n\n"
120 " -numericHigh\n"
121 " Prioritize numeric characters over other characters in string comparisons.\n"
122 " Also ranks numeric character sets with fewer characters below those with more characters.\n\n"
123 " -nonDominateSort\n"
124 " Perform non-dominated sorting when multiple sort columns are provided.\n"
125 " Note: Non-dominated sorting only works for numeric columns.\n\n"
126 " -hypervolume=<ref1>,<ref2>,...\n"
127 " Requires -nonDominateSort. Computes the hypervolume of the feasible\n"
128 " first (Pareto) front relative to the given reference point and stores it\n"
129 " in the 'Hypervolume' parameter (one value per page). Give one reference\n"
130 " value per -column objective, in the same order; each should be a worst-\n"
131 " case (dominated) value for that objective. Works for any number of\n"
132 " objectives.\n\n"
133 " -majorOrder=row|column\n"
134 " Set the major order for data storage, either row-major or column-major.\n\n"
135 "Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n";
136
137typedef struct
138{
139 char *name;
140 long index, type;
141 short decreasing_order, maximize_order, absolute;
142 double *data;
143 void *column_data;
144 int32_t element_size;
146
147static char *order_mode[5] = {
148 "increasing",
149 "decreasing",
150 "minimize",
151 "maximize",
152 "absolute",
153};
154
155long SDDS_SortRows(SDDS_DATASET *SDDS_dataset, SORT_REQUEST *xsort_request, long xsort_requests, long non_dominate_sort);
156long SDDS_UnsetDuplicateRows(SDDS_DATASET *SDDS_dataset, SORT_REQUEST *xsort_request, long xsort_requests, long provideIdenticalCount);
157
158long SDDS_SortAll(SDDS_DATASET *SDDS_input, SDDS_DATASET *SDDS_output, SORT_REQUEST *xsort_request, long xsort_requests,
159 SORT_REQUEST *xsort_parameter, long xsort_parameters, long uniqueRows, long provideIdenticalCount,
160 long pipeFlags, long non_dominate_sort);
161
162double *read_constr_violation(SDDS_DATASET *SDDS_dataset);
163
164long numericHigh = 0, constDefined = 0;
165/* Hypervolume request (off by default; when off, output is unchanged). */
166static long hypervolume_flag = 0;
167static long hv_nref = 0;
168static double *hv_reference = NULL;
169
170int main(int argc, char **argv) {
171 SDDS_DATASET SDDS_input, SDDS_output, SDDS_tmp;
172 char *input, *output;
173 long i_arg, non_dominate_sort = 0;
174 SCANNED_ARG *s_arg;
175
176 long tmpfile_used, sort_requests, noWarnings, uniqueRows, provideIdenticalCount, tmpfileForInternalPipe;
177 long sort_parameters;
178 SORT_REQUEST *sort_request, *sort_parameter;
179 unsigned long pipeFlags, majorOrderFlag;
180 short columnMajorOrder = -1;
181
183 argc = scanargs(&s_arg, argc, argv);
184 if (argc < 2) {
185 bomb(NULL, USAGE);
186 }
187
188 input = output = NULL;
189 tmpfile_used = sort_requests = noWarnings = sort_parameters = tmpfileForInternalPipe = 0;
190 sort_request = sort_parameter = NULL;
191 pipeFlags = 0;
192 uniqueRows = provideIdenticalCount = 0;
193 for (i_arg = 1; i_arg < argc; i_arg++) {
194 if (s_arg[i_arg].arg_type == OPTION) {
195 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
196 case SET_MAJOR_ORDER:
197 majorOrderFlag = 0;
198 s_arg[i_arg].n_items--;
199 if (s_arg[i_arg].n_items > 0 &&
200 (!scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
201 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
202 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
203 SDDS_Bomb("invalid -majorOrder syntax/values");
204 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
205 columnMajorOrder = 1;
206 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
207 columnMajorOrder = 0;
208 break;
209 case SET_NON_DOMINATE_SORT:
210 non_dominate_sort = 1;
211 break;
212 case SET_HYPERVOLUME:
213 if (s_arg[i_arg].n_items < 2)
214 SDDS_Bomb("invalid -hypervolume syntax; give a reference point: -hypervolume=<ref1>,<ref2>,...");
215 hypervolume_flag = 1;
216 hv_nref = s_arg[i_arg].n_items - 1;
217 hv_reference = trealloc(hv_reference, sizeof(*hv_reference) * hv_nref);
218 {
219 long jref;
220 for (jref = 0; jref < hv_nref; jref++)
221 if (sscanf(s_arg[i_arg].list[jref + 1], "%lf", &hv_reference[jref]) != 1)
222 SDDS_Bomb("invalid -hypervolume reference value");
223 }
224 break;
225 case SET_COLUMN:
226 if (s_arg[i_arg].n_items < 2 || s_arg[i_arg].n_items > 4)
227 SDDS_Bomb("invalid -column syntax");
228 sort_request = trealloc(sort_request, sizeof(*sort_request) * (sort_requests + 1));
229 sort_request[sort_requests].name = s_arg[i_arg].list[1];
230 sort_request[sort_requests].maximize_order = 0;
231 sort_request[sort_requests].decreasing_order = 0;
232 sort_request[sort_requests].absolute = 0;
233 if (s_arg[i_arg].n_items >= 3) {
234 int j;
235 for (j = 2; j < s_arg[i_arg].n_items; j++) {
236 switch (match_string(s_arg[i_arg].list[j], order_mode, 5, 0)) {
237 case 0:
238 break;
239 case 1:
240 sort_request[sort_requests].decreasing_order = 1;
241 break;
242 case 2:
243 break;
244 case 3:
245 sort_request[sort_requests].maximize_order = 1;
246 break;
247 case 4:
248 sort_request[sort_requests].absolute = 1;
249 break;
250 default:
251 fprintf(stderr, "unknown sort order specified--give 'increasing' or 'decreasing' for dominated sorting\n or'maximize' or 'minimize' for non-dominated-sorting.\n");
252 exit(EXIT_FAILURE);
253 break;
254 }
255 }
256 }
257 sort_requests++;
258 break;
259 case SET_PARAMETER:
260 if (s_arg[i_arg].n_items < 2 || s_arg[i_arg].n_items > 3)
261 SDDS_Bomb("invalid -parameter syntax");
262 sort_parameter = trealloc(sort_parameter, sizeof(*sort_parameter) * (sort_parameters + 1));
263 sort_parameter[sort_parameters].name = s_arg[i_arg].list[1];
264 if (s_arg[i_arg].n_items == 3) {
265 if ((sort_parameter[sort_parameters].decreasing_order = match_string(s_arg[i_arg].list[2], order_mode, 2, 0)) < 0)
266 SDDS_Bomb("unknown sort order specified--give 'increasing' or 'decreasing'");
267 } else
268 sort_parameter[sort_parameters].decreasing_order = 0;
269 sort_parameters++;
270 break;
271 case SET_NOWARNINGS:
272 noWarnings = 1;
273 break;
274 case SET_NUMERICHIGH:
275 numericHigh = 1;
276 break;
277 case SET_PIPE:
278 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
279 SDDS_Bomb("invalid -pipe syntax");
280 break;
281 case SET_UNIQUE:
282 uniqueRows = 1;
283 if (s_arg[i_arg].n_items > 1) {
284 str_tolower(s_arg[i_arg].list[1]);
285 if (s_arg[i_arg].n_items > 2 ||
286 strncmp("count", s_arg[i_arg].list[1], strlen(s_arg[i_arg].list[1])) != 0)
287 SDDS_Bomb("invalid -unique syntax");
288 provideIdenticalCount = 1;
289 }
290 break;
291 default:
292 fprintf(stderr, "error: unknown switch: %s\n", s_arg[i_arg].list[0]);
293 exit(EXIT_FAILURE);
294 break;
295 }
296 } else {
297 if (input == NULL)
298 input = s_arg[i_arg].list[0];
299 else if (output == NULL)
300 output = s_arg[i_arg].list[0];
301 else
302 SDDS_Bomb("too many filenames");
303 }
304 }
305
306 if (!sort_requests && !sort_parameters)
307 SDDS_Bomb("No sorting requests!");
308 processFilenames("sddssort", &input, &output, pipeFlags, noWarnings, &tmpfile_used);
309 if (!SDDS_InitializeInput(&SDDS_input, input)) {
310 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
311 exit(EXIT_FAILURE);
312 }
313 if (sort_requests <= 1)
314 non_dominate_sort = 0;
315
316 if (hypervolume_flag) {
317 if (!non_dominate_sort)
318 SDDS_Bomb("-hypervolume requires -nonDominateSort with two or more -column objectives");
319 if (hv_nref != sort_requests)
320 SDDS_Bomb("-hypervolume reference point must have one value per -column objective");
321 }
322
323 if (SDDS_input.layout.popenUsed) {
324 /* SDDS library has opened the file using a command on a pipe, usually for
325 * decompression in the absence of the zlib library.
326 */
327 pid_t pid;
328 char tmpfileName[1024];
329 pid = getpid();
330 sprintf(tmpfileName, "/tmp/sddssort.%ld", (long)pid);
331 tmpfileForInternalPipe = 1;
332 if (!SDDS_InitializeCopy(&SDDS_tmp, &SDDS_input, tmpfileName, "w")) {
333 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
334 exit(EXIT_FAILURE);
335 }
336 if (columnMajorOrder != -1)
337 SDDS_tmp.layout.data_mode.column_major = columnMajorOrder;
338 else
339 SDDS_tmp.layout.data_mode.column_major = SDDS_input.layout.data_mode.column_major;
340 if (non_dominate_sort) {
341 if (!SDDS_DefineSimpleColumn(&SDDS_output, "Rank", NULL, SDDS_LONG) ||
342 !SDDS_DefineSimpleColumn(&SDDS_output, "CrowdingDistance", NULL, SDDS_DOUBLE)) {
343 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
344 exit(EXIT_FAILURE);
345 }
346 if (SDDS_CheckColumn(&SDDS_input, "ConstraintsViolation", NULL, SDDS_ANY_NUMERIC_TYPE, NULL) != SDDS_CHECK_OK) {
347 if (!SDDS_DefineSimpleColumn(&SDDS_output, "ConstraintsViolation", NULL, SDDS_DOUBLE))
348 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
349 constDefined = 1;
350 }
351 }
352
353 if (!SDDS_WriteLayout(&SDDS_tmp)) {
354 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
355 exit(EXIT_FAILURE);
356 }
357 while (SDDS_ReadPage(&SDDS_input) > 0) {
358 if (!SDDS_CopyPage(&SDDS_tmp, &SDDS_input) || !SDDS_WritePage(&SDDS_tmp)) {
359 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
360 exit(EXIT_FAILURE);
361 }
362 }
363 if (!SDDS_Terminate(&SDDS_tmp)) {
364 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
365 exit(EXIT_FAILURE);
366 }
367 if (!SDDS_InitializeInput(&SDDS_input, tmpfileName)) {
368 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
369 exit(EXIT_FAILURE);
370 }
371 }
372 if (!SDDS_InitializeCopy(&SDDS_output, &SDDS_input, output, "w")) {
373 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
374 exit(EXIT_FAILURE);
375 }
376 if (columnMajorOrder != -1)
377 SDDS_output.layout.data_mode.column_major = columnMajorOrder;
378 else
379 SDDS_output.layout.data_mode.column_major = SDDS_input.layout.data_mode.column_major;
380 if (provideIdenticalCount &&
381 !SDDS_DefineSimpleColumn(&SDDS_output, "IdenticalCount", NULL, SDDS_LONG64)) {
382 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
383 exit(EXIT_FAILURE);
384 }
385 if (non_dominate_sort) {
386 if (!SDDS_DefineSimpleColumn(&SDDS_output, "Rank", NULL, SDDS_LONG) ||
387 !SDDS_DefineSimpleColumn(&SDDS_output, "CrowdingDistance", NULL, SDDS_DOUBLE)) {
388 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
389 exit(EXIT_FAILURE);
390 }
391 if (SDDS_CheckColumn(&SDDS_input, "ConstraintsViolation", NULL, SDDS_ANY_NUMERIC_TYPE, NULL) != SDDS_CHECK_OK) {
392 if (!SDDS_DefineSimpleColumn(&SDDS_output, "ConstraintsViolation", NULL, SDDS_DOUBLE))
393 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
394 constDefined = 1;
395 }
396 if (hypervolume_flag &&
397 !SDDS_DefineSimpleParameter(&SDDS_output, "Hypervolume", NULL, SDDS_DOUBLE))
398 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
399 }
400 if (!SDDS_WriteLayout(&SDDS_output))
401 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
402 if (!SDDS_SortAll(&SDDS_input, &SDDS_output, sort_request, sort_requests, sort_parameter, sort_parameters,
403 uniqueRows, provideIdenticalCount, pipeFlags, non_dominate_sort)) {
404 SDDS_SetError("Problem sorting data");
405 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
406 }
407 if (!SDDS_Terminate(&SDDS_input) || !SDDS_Terminate(&SDDS_output)) {
408 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
409 exit(EXIT_FAILURE);
410 }
411 if (tmpfile_used && !replaceFileAndBackUp(input, output))
412 exit(EXIT_FAILURE);
413 free_scanargs(&s_arg, argc);
414 /* if (tmpfileForInternalPipe)
415 system("rm /tmp/tmpfile"); */
416 return EXIT_SUCCESS;
417}
418
419static SDDS_DATASET *SDDS_sort;
420static SORT_REQUEST *sort_request;
421static long sort_requests;
422static int64_t *sort_row_index;
423
424int SDDS_CompareData(SDDS_DATASET *SDDS_dataset, short type, short absolute, void *data1, void *data2) {
425 long double ldouble1, ldouble2;
426 double double1, double2;
427 float float1, float2;
428 int64_t long64_1, long64_2;
429 int32_t long1, long2;
430 int16_t short1, short2;
431 char char1, char2;
432 uint64_t magnitude1, magnitude2;
433
434 (void)SDDS_dataset;
435
436 if (!absolute) {
437 switch (type) {
438 case SDDS_LONGDOUBLE:
439 ldouble1 = *(long double *)data1;
440 ldouble2 = *(long double *)data2;
441 if (isnan(ldouble1))
442 return isnan(ldouble2) ? 0 : 1;
443 if (isnan(ldouble2))
444 return -1;
445 return ldouble1 > ldouble2 ? 1 : (ldouble1 < ldouble2 ? -1 : 0);
446 case SDDS_DOUBLE:
447 double1 = *(double *)data1;
448 double2 = *(double *)data2;
449 if (isnan(double1))
450 return isnan(double2) ? 0 : 1;
451 if (isnan(double2))
452 return -1;
453 return double1 > double2 ? 1 : (double1 < double2 ? -1 : 0);
454 case SDDS_FLOAT:
455 float1 = *(float *)data1;
456 float2 = *(float *)data2;
457 if (isnan(float1))
458 return isnan(float2) ? 0 : 1;
459 if (isnan(float2))
460 return -1;
461 return float1 > float2 ? 1 : (float1 < float2 ? -1 : 0);
462 case SDDS_LONG64:
463 long64_1 = *(int64_t *)data1;
464 long64_2 = *(int64_t *)data2;
465 return long64_1 > long64_2 ? 1 : (long64_1 < long64_2 ? -1 : 0);
466 case SDDS_LONG:
467 long1 = *(int32_t *)data1;
468 long2 = *(int32_t *)data2;
469 return long1 > long2 ? 1 : (long1 < long2 ? -1 : 0);
470 case SDDS_SHORT:
471 short1 = *(short *)data1;
472 short2 = *(short *)data2;
473 return short1 > short2 ? 1 : (short1 < short2 ? -1 : 0);
474 case SDDS_ULONG64:
475 if (*(uint64_t *)data1 > *(uint64_t *)data2)
476 return 1;
477 if (*(uint64_t *)data1 < *(uint64_t *)data2)
478 return -1;
479 return 0;
480 case SDDS_ULONG:
481 if (*(uint32_t *)data1 > *(uint32_t *)data2)
482 return 1;
483 if (*(uint32_t *)data1 < *(uint32_t *)data2)
484 return -1;
485 return 0;
486 case SDDS_USHORT:
487 if (*(unsigned short *)data1 > *(unsigned short *)data2)
488 return 1;
489 if (*(unsigned short *)data1 < *(unsigned short *)data2)
490 return -1;
491 return 0;
492 case SDDS_CHARACTER:
493 char1 = *(char *)data1;
494 char2 = *(char *)data2;
495 return char1 > char2 ? 1 : (char1 < char2 ? -1 : 0);
496 case SDDS_STRING:
497 if (numericHigh)
498 return (strcmp_nh(*(char **)data1, *(char **)data2));
499 else
500 return (strcmp(*(char **)data1, *(char **)data2));
501 default:
502 SDDS_SetError("Problem doing data comparison--invalid data type (SDDS_CompareData)");
503 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
504 exit(EXIT_FAILURE);
505 }
506 } else {
507 switch (type) {
508 case SDDS_LONGDOUBLE:
509 ldouble1 = fabsl(*(long double *)data1);
510 ldouble2 = fabsl(*(long double *)data2);
511 if (isnan(ldouble1))
512 return isnan(ldouble2) ? 0 : 1;
513 if (isnan(ldouble2))
514 return -1;
515 return ldouble1 > ldouble2 ? 1 : (ldouble1 < ldouble2 ? -1 : 0);
516 case SDDS_DOUBLE:
517 double1 = fabs(*(double *)data1);
518 double2 = fabs(*(double *)data2);
519 if (isnan(double1))
520 return isnan(double2) ? 0 : 1;
521 if (isnan(double2))
522 return -1;
523 return double1 > double2 ? 1 : (double1 < double2 ? -1 : 0);
524 case SDDS_FLOAT:
525 float1 = fabsf(*(float *)data1);
526 float2 = fabsf(*(float *)data2);
527 if (isnan(float1))
528 return isnan(float2) ? 0 : 1;
529 if (isnan(float2))
530 return -1;
531 return float1 > float2 ? 1 : (float1 < float2 ? -1 : 0);
532 case SDDS_LONG64:
533 long64_1 = *(int64_t *)data1;
534 long64_2 = *(int64_t *)data2;
535 magnitude1 = long64_1 < 0 ? -(uint64_t)long64_1 : (uint64_t)long64_1;
536 magnitude2 = long64_2 < 0 ? -(uint64_t)long64_2 : (uint64_t)long64_2;
537 return magnitude1 > magnitude2 ? 1 : (magnitude1 < magnitude2 ? -1 : 0);
538 case SDDS_LONG:
539 long1 = *(int32_t *)data1;
540 long2 = *(int32_t *)data2;
541 magnitude1 = long1 < 0 ? (uint64_t)(-(int64_t)long1) : (uint64_t)long1;
542 magnitude2 = long2 < 0 ? (uint64_t)(-(int64_t)long2) : (uint64_t)long2;
543 return magnitude1 > magnitude2 ? 1 : (magnitude1 < magnitude2 ? -1 : 0);
544 case SDDS_SHORT:
545 short1 = *(short *)data1;
546 short2 = *(short *)data2;
547 magnitude1 = short1 < 0 ? (uint64_t)(-(int32_t)short1) : (uint64_t)short1;
548 magnitude2 = short2 < 0 ? (uint64_t)(-(int32_t)short2) : (uint64_t)short2;
549 return magnitude1 > magnitude2 ? 1 : (magnitude1 < magnitude2 ? -1 : 0);
550 case SDDS_ULONG64:
551 if (*(uint64_t *)data1 > *(uint64_t *)data2)
552 return (1);
553 if (*(uint64_t *)data1 < *(uint64_t *)data2)
554 return (-1);
555 return (0);
556 case SDDS_ULONG:
557 if (*(uint32_t *)data1 > *(uint32_t *)data2)
558 return (1);
559 if (*(uint32_t *)data1 < *(uint32_t *)data2)
560 return (-1);
561 return (0);
562 case SDDS_USHORT:
563 if (*(unsigned short *)data1 > *(unsigned short *)data2)
564 return (1);
565 if (*(unsigned short *)data1 < *(unsigned short *)data2)
566 return (-1);
567 return (0);
568 case SDDS_CHARACTER:
569 char1 = *(char *)data1;
570 char2 = *(char *)data2;
571 magnitude1 = char1 < 0 ? (uint64_t)(-(int16_t)char1) : (uint64_t)char1;
572 magnitude2 = char2 < 0 ? (uint64_t)(-(int16_t)char2) : (uint64_t)char2;
573 return magnitude1 > magnitude2 ? 1 : (magnitude1 < magnitude2 ? -1 : 0);
574 case SDDS_STRING:
575 if (numericHigh)
576 return (strcmp_nh(*(char **)data1, *(char **)data2));
577 else
578 return (strcmp(*(char **)data1, *(char **)data2));
579 default:
580 SDDS_SetError("Problem doing data comparison--invalid data type (SDDS_CompareData)");
581 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
582 exit(EXIT_FAILURE);
583 }
584 }
585}
586
587int SDDS_CompareRows(const void *vrow1, const void *vrow2) {
588 int64_t row1, row2;
589 long i;
590 int comparison;
591 void *data1, *data2;
592 row1 = *(int64_t *)vrow1;
593 row2 = *(int64_t *)vrow2;
594
595 for (i = 0; i < sort_requests; i++) {
596 data1 = (char *)sort_request[i].column_data + row1 * sort_request[i].element_size;
597 data2 = (char *)sort_request[i].column_data + row2 * sort_request[i].element_size;
598 if ((comparison = SDDS_CompareData(SDDS_sort, sort_request[i].type, sort_request[i].absolute,
599 data1, data2))) {
600 return (sort_request[i].decreasing_order ? -comparison : comparison);
601 }
602 }
603 return (0);
604}
605
606long SDDS_SwapRows(SDDS_DATASET *SDDS_dataset, int64_t row1, int64_t row2) {
607#define SWAP_BUFFER_SIZE 16
608 static char buffer[SWAP_BUFFER_SIZE];
609 void **data;
610 long i, size;
611 data = SDDS_dataset->data;
612#if defined(DEBUG)
613 fprintf(stderr, "swapping row %" PRId64 " with row %" PRId64 "\n", row1, row2);
614#endif
615 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
616 if ((size = SDDS_GetTypeSize(SDDS_dataset->layout.column_definition[i].type)) > SWAP_BUFFER_SIZE) {
617 SDDS_SetError("Unable to swap rows--swap buffer is too small (SDDS_SwapRows)");
618 return (0);
619 }
620#if defined(DEBUG)
621 if (SDDS_dataset->layout.column_definition[i].type == SDDS_STRING)
622 fprintf(stderr, " %s <--> %s\n", *(char **)((char *)(data[i]) + row1 * size), *(char **)((char *)(data[i]) + row2 * size));
623#endif
624 memcpy((char *)buffer, (char *)(data[i]) + row1 * size, size);
625 memcpy((char *)(data[i]) + row1 * size, (char *)(data[i]) + row2 * size, size);
626 memcpy((char *)(data[i]) + row2 * size, (char *)buffer, size);
627 }
628 return (1);
629}
630
631long SDDS_SortRows(SDDS_DATASET *SDDS_dataset, SORT_REQUEST *xsort_request, long xsort_requests, long non_dominate_sort) {
632 int64_t i, j, k, rows;
633 int64_t *row_location;
634 char s[1024];
635 double **data = NULL, *dist = NULL, *const_violation = NULL;
636 int32_t *rank = NULL;
637 population pop;
638 long *maximize = NULL;
639 double hv_value = 0;
640
641 SDDS_sort = SDDS_dataset;
642 sort_request = xsort_request;
643 sort_requests = xsort_requests;
644 if ((rows = SDDS_CountRowsOfInterest(SDDS_sort)) < 0)
645 return (0);
646
647 for (i = 0; i < sort_requests; i++) {
648 if ((sort_request[i].index = SDDS_GetColumnIndex(SDDS_sort, sort_request[i].name)) < 0) {
649 sprintf(s, "column name \"%s\" is not recognized(SDDS_GetColumnIndex)", sort_request[i].name);
650 SDDS_SetError(s);
651 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
652 return (0);
653 }
654 sort_request[i].type = SDDS_GetColumnType(SDDS_sort, sort_request[i].index);
655 sort_request[i].element_size = SDDS_GetTypeSize(sort_request[i].type);
656 if (sort_request[i].element_size <= 0 ||
657 !(sort_request[i].column_data = SDDS_GetInternalColumn(SDDS_sort, sort_request[i].name))) {
658 SDDS_SetError("Problem getting internal column data for sort (SDDS_SortRows)");
659 return 0;
660 }
661 }
662 if (non_dominate_sort) {
663 data = (double **)malloc(sizeof(*data) * sort_requests);
664 maximize = (long *)malloc(sizeof(*maximize) * sort_requests);
665 for (i = 0; i < sort_requests; i++) {
666 if (sort_request[i].type == SDDS_STRING) {
667 fprintf(stderr, "Non-dominated sort is not available for string column.\n");
668 exit(EXIT_FAILURE);
669 }
670 if (!(data[i] = (double *)SDDS_GetColumnInDoubles(SDDS_sort, sort_request[i].name))) {
671 SDDS_SetError("Problem performing sort");
672 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
673 exit(EXIT_FAILURE);
674 }
675 maximize[i] = sort_request[i].maximize_order;
676 }
677 const_violation = read_constr_violation(SDDS_sort);
678 fill_population(&pop, rows, sort_requests, data, maximize, const_violation);
679 sort_row_index = non_dominated_sort(&pop);
680 rank = (int32_t *)malloc(sizeof(*rank) * rows);
681 dist = (double *)malloc(sizeof(*dist) * rows);
682 if (!const_violation)
683 const_violation = calloc(rows, sizeof(*const_violation));
684 for (i = 0; i < rows; i++) {
685 rank[i] = pop.ind[sort_row_index[i]].rank;
686 dist[i] = pop.ind[sort_row_index[i]].crowd_dist;
687 const_violation[i] = pop.ind[sort_row_index[i]].constr_violation;
688 }
689 if (hypervolume_flag) {
690 /* reference is given in user (column) units; convert to the internal
691 * minimization sense used by pop.ind[].obj (maximized objectives negated) */
692 double *ref_internal = (double *)malloc(sizeof(*ref_internal) * sort_requests);
693 for (i = 0; i < sort_requests; i++)
694 ref_internal[i] = maximize[i] ? -hv_reference[i] : hv_reference[i];
695 hv_value = compute_hypervolume(&pop, ref_internal);
696 free(ref_internal);
697 }
698 free_pop_mem(&pop);
699 for (i = 0; i < sort_requests; i++)
700 free(data[i]);
701 free(data);
702 free(maximize);
703 } else {
704 sort_row_index = tmalloc(sizeof(*sort_row_index) * rows);
705 for (i = 0; i < rows; i++)
706 sort_row_index[i] = i;
707 /* After this sort, sort_row_index will contain the indices of the rows
708 * in sorted order
709 */
710 qsort((void *)sort_row_index, rows, sizeof(*sort_row_index), SDDS_CompareRows);
711
712 /* create an array to give the location in the sort_row_index array of
713 * a particular row
714 */
715#if defined(DEBUG)
716 fprintf(stderr, "new row order:\n");
717 for (i = 0; i < rows; i++)
718 fprintf(stderr, "%" PRId64 " %" PRId64 "\n", i, sort_row_index[i]);
719 fprintf(stderr, "\n");
720#endif
721 }
722 row_location = tmalloc(sizeof(*sort_row_index) * rows);
723 for (i = 0; i < rows; i++)
724 row_location[sort_row_index[i]] = i;
725 for (i = 0; i < rows; i++) {
726 if ((j = sort_row_index[i]) != i) {
727 /* move this row from position i to position j, where it belongs */
728 if (!SDDS_SwapRows(SDDS_sort, i, j)) {
729 SDDS_SetError("Problem swapping rows after index sort (SDDS_SortRows");
730 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
731 exit(EXIT_FAILURE);
732 }
733 /* adjust the indices to reflect the swap */
734 sort_row_index[i] = i;
735 k = row_location[i];
736 row_location[i] = i;
737 sort_row_index[k] = j;
738 row_location[j] = k;
739 }
740#if defined(DEBUG)
741 fprintf(stderr, "new row order:\n");
742 for (j = 0; j < rows; j++)
743 fprintf(stderr, "%" PRId64 " %" PRId64 "\n", j, sort_row_index[j]);
744 fprintf(stderr, "\n");
745#endif
746 }
747 if (non_dominate_sort) {
748 if (SDDS_SetColumn(SDDS_sort, SDDS_SET_BY_NAME, rank, rows, "Rank", NULL) != 1 ||
749 SDDS_SetColumn(SDDS_sort, SDDS_SET_BY_NAME, dist, rows, "CrowdingDistance", NULL) != 1 ||
750 SDDS_SetColumn(SDDS_sort, SDDS_SET_BY_NAME, const_violation, rows, "ConstraintsViolation", NULL) != 1) {
751 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
752 exit(EXIT_FAILURE);
753 }
754 free(rank);
755 free(dist);
756 free(const_violation);
757 if (hypervolume_flag &&
758 !SDDS_SetParameters(SDDS_sort, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, "Hypervolume", hv_value, NULL)) {
759 SDDS_SetError("Problem setting Hypervolume parameter");
760 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
761 exit(EXIT_FAILURE);
762 }
763 }
764 free(sort_row_index);
765 free(row_location);
766 return 1;
767}
768
769long SDDS_UnsetDuplicateRows(SDDS_DATASET *SDDS_dataset, SORT_REQUEST *xsort_request, long xsort_requests, long provideIdenticalCount) {
770 int64_t rows, i, j;
771 int64_t *identicalCount;
772 int32_t *rowFlag;
773 char s[1024];
774
775 SDDS_sort = SDDS_dataset;
776 sort_request = xsort_request;
777 sort_requests = xsort_requests;
778
779 for (i = 0; i < sort_requests; i++) {
780 if ((sort_request[i].index = SDDS_GetColumnIndex(SDDS_sort, sort_request[i].name)) < 0) {
781 sprintf(s, "column name \"%s\" is not recognized(SDDS_GetColumnIndex)", sort_request[i].name);
782 SDDS_SetError(s);
783 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
784 return 0;
785 }
786 sort_request[i].type = SDDS_GetColumnType(SDDS_sort, sort_request[i].index);
787 }
788
789 if ((rows = SDDS_CountRowsOfInterest(SDDS_sort)) < 0)
790 return (0);
791
792 rowFlag = tmalloc(sizeof(*rowFlag) * rows);
793 identicalCount = tmalloc(sizeof(*identicalCount) * rows);
794 for (i = 0; i < rows; i++)
795 rowFlag[i] = identicalCount[i] = 1;
796
797 for (i = 0; i < rows - 1; i++) {
798 if (!rowFlag[i])
799 continue;
800 for (j = i + 1; j < rows; j++) {
801 if (rowFlag[j]) {
802 if (SDDS_CompareRows(&i, &j) == 0) {
803 identicalCount[i] += 1;
804 rowFlag[j] = 0;
805 } else
806 break;
807 }
808 }
809 }
810 if (!SDDS_AssertRowFlags(SDDS_sort, SDDS_FLAG_ARRAY, rowFlag, rows)) {
811 free(rowFlag);
812 free(identicalCount);
813 return 0;
814 }
815 if (provideIdenticalCount && !SDDS_SetColumn(SDDS_sort, SDDS_SET_BY_NAME, identicalCount, rows, "IdenticalCount")) {
816 free(rowFlag);
817 free(identicalCount);
818 return 0;
819 }
820 free(rowFlag);
821 free(identicalCount);
822 return 1;
823}
824
825static SORT_REQUEST *sort_parameter;
826static long sort_parameters;
827static SDDS_DATASET *SDDS_sortpage;
828
829int SDDS_ComparePages(const void *vpage1, const void *vpage2) {
830 /* I'm assuming that a double is large enough to store any of the data types,
831 * including a pointer
832 */
833 static int32_t page1, page2;
834 long i;
835 int comparison;
836
837 page1 = *(int32_t *)vpage1;
838 page2 = *(int32_t *)vpage2;
839
840 for (i = 0; i < sort_parameters; i++) {
841 if ((comparison = SDDS_CompareData(SDDS_sortpage, sort_parameter[i].type, sort_parameter[i].absolute,
842 (void *)&(sort_parameter[i].data[page1]), (void *)&(sort_parameter[i].data[page2])))) {
843 /* if (sort_parameter[i].type==SDDS_STRING) {
844 * free(*((char**)&(sort_parameter[i].data[page1])));
845 * free(*((char**)&(sort_parameter[i].data[page2])));
846 * } */
847 return (sort_parameter[i].decreasing_order ? -comparison : comparison);
848 }
849 /* if (sort_parameter[i].type==SDDS_STRING) {
850 * free(*((char**)&(sort_parameter[i].data[page1])));
851 * free(*((char**)&(sort_parameter[i].data[page2])));
852 * } */
853 }
854 return (0);
855}
856
857long SDDS_SortAll(SDDS_DATASET *SDDS_inputx, SDDS_DATASET *SDDS_outputx, SORT_REQUEST *xsort_request,
858 long xsort_requests, SORT_REQUEST *xsort_parameter, long xsort_parameters, long uniqueRows,
859 long provideIdenticalCount, long xpipeFlags, long non_dominate_sort) {
860 long i, j, k, pages;
861 int32_t *xsort_page_index;
862 char s[1024];
863 SDDS_DATASET *tmp_datasets;
864
865 tmp_datasets = NULL;
866 SDDS_sortpage = SDDS_inputx;
867 sort_parameter = xsort_parameter;
868 sort_parameters = xsort_parameters;
869 sort_request = xsort_request;
870 sort_requests = xsort_requests;
871 xsort_page_index = NULL;
872 pages = i = j = k = 0;
873 for (i = 0; i < sort_parameters; i++) {
874 if ((sort_parameter[i].index = SDDS_GetParameterIndex(SDDS_sortpage, sort_parameter[i].name)) < 0) {
875 sprintf(s, "Unable to get parameter value--parameter name \"%s\" is not recognized(SDDS_GetParameterIndex)", sort_parameter[i].name);
876 SDDS_SetError(s);
877 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
878 return (0);
879 }
880 sort_parameter[i].type = SDDS_GetParameterType(SDDS_sortpage, sort_parameter[i].index);
881 }
882 if (sort_parameters) {
883 if (xpipeFlags == 0 && !SDDS_sortpage->layout.gzipFile)
885 for (i = 0; i < sort_parameters; i++)
886 sort_parameter[i].data = NULL;
887 while (SDDS_ReadPage(SDDS_sortpage) > 0) {
888 if (xpipeFlags || SDDS_sortpage->layout.gzipFile) {
889 /* copy each page of sortpage into tmp_datasets indexed by the pages, i.e.
890 * tmp_datasets[pages] contains only one page */
891 tmp_datasets = realloc(tmp_datasets, sizeof(*tmp_datasets) * (pages + 1));
892 if (!SDDS_InitializeCopy(&tmp_datasets[pages], SDDS_sortpage, NULL, "m")) {
893 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
894 return (0);
895 }
896 if (!SDDS_CopyPage(&tmp_datasets[pages], SDDS_sortpage)) {
897 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
898 return (0);
899 }
900 }
901 for (i = 0; i < sort_parameters; i++) {
902 sort_parameter[i].data = realloc(sort_parameter[i].data, sizeof(*sort_parameter[i].data) * (pages + 1));
903
904 if (!SDDS_GetParameterByIndex(SDDS_sortpage, sort_parameter[i].index, &(sort_parameter[i].data[pages]))) {
905 SDDS_SetError("Problem getting parameter value for sort (SDDS_SortAll)");
906 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
907 exit(EXIT_FAILURE);
908 }
909 }
910 pages++;
911 }
912 /* sort pages by parameter */
913 xsort_page_index = tmalloc(sizeof(*xsort_page_index) * pages);
914 for (k = 0; k < pages; k++)
915 xsort_page_index[k] = k;
916 if (pages > 1)
917 qsort((void *)xsort_page_index, pages, sizeof(*xsort_page_index), SDDS_ComparePages);
918
919 /* sort_page_index=xsort_page_index; */
920 for (i = 0; i < pages; i++) {
921 j = xsort_page_index[i];
922 if (xpipeFlags || SDDS_sortpage->layout.gzipFile) {
923 if (!SDDS_CopyPage(SDDS_outputx, &tmp_datasets[j])) {
924 SDDS_SetError("Problem copying data from memory");
925 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
926 exit(EXIT_FAILURE);
927 }
928 if (!SDDS_Terminate(&tmp_datasets[j])) {
929 SDDS_SetError("Problem terminate datasets");
930 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
931 exit(EXIT_FAILURE);
932 }
933 } else {
934 if (!SDDS_GotoPage(SDDS_sortpage, j + 1)) {
935 SDDS_SetError("Problem goto page");
936 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
937 exit(EXIT_FAILURE);
938 }
939 if (SDDS_ReadPage(SDDS_sortpage) < 1) {
940 SDDS_SetError("Problem read page");
941 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
942 exit(EXIT_FAILURE);
943 }
944 if (!SDDS_CopyPage(SDDS_outputx, SDDS_sortpage)) {
945 SDDS_SetError("Problem copying data");
946 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
947 exit(EXIT_FAILURE);
948 }
949 }
950 if (sort_requests) {
951 if (SDDS_CountRowsOfInterest(SDDS_outputx) > 0) {
952 if (!SDDS_SortRows(SDDS_outputx, sort_request, sort_requests, non_dominate_sort)) {
953 SDDS_SetError("Problem performing sort");
954 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
955 exit(EXIT_FAILURE);
956 }
957 if (uniqueRows && !SDDS_UnsetDuplicateRows(SDDS_outputx, sort_request, sort_requests, provideIdenticalCount)) {
958 SDDS_SetError("Problem marking duplicate rows.");
959 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
960 exit(EXIT_FAILURE);
961 }
962 }
963 }
964 if (!SDDS_WritePage(SDDS_outputx)) {
965 SDDS_SetError("Problem writing data to output file");
966 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
967 exit(EXIT_FAILURE);
968 }
969 }
970 } else {
971 while (SDDS_ReadPage(SDDS_inputx) > 0) {
972 if (!SDDS_CopyPage(SDDS_outputx, SDDS_inputx)) {
973 SDDS_SetError("Problem copying data for output file");
974 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
975 exit(EXIT_FAILURE);
976 }
977 if (SDDS_CountRowsOfInterest(SDDS_outputx) > 0) {
978 if (!SDDS_SortRows(SDDS_outputx, sort_request, sort_requests, non_dominate_sort)) {
979 SDDS_SetError("Problem performing sort");
980 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
981 exit(EXIT_FAILURE);
982 }
983 if (uniqueRows && !SDDS_UnsetDuplicateRows(SDDS_outputx, sort_request, sort_requests, provideIdenticalCount)) {
984 SDDS_SetError("Problem marking duplicate rows.");
985 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
986 exit(EXIT_FAILURE);
987 }
988 }
989 if (!SDDS_WritePage(SDDS_outputx)) {
990 SDDS_SetError("Problem writing data to output file");
991 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
992 exit(EXIT_FAILURE);
993 }
994 }
995 }
996 if (tmp_datasets)
997 free(tmp_datasets);
998 if (xsort_page_index)
999 free(xsort_page_index);
1000 return 1;
1001}
1002
1003double *read_constr_violation(SDDS_DATASET *SDDS_dataset) {
1004 double *const_violation = NULL, **data = NULL;
1005 int32_t columns, constraints, j;
1006 int64_t i, rows;
1007 char **columnName = NULL;
1008
1009 columns = constraints = 0;
1010 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
1011 if (!constDefined && !(const_violation = (double *)SDDS_GetColumnInDoubles(SDDS_dataset, "ConstraintsViolation")))
1012 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1013 else {
1014 if (!(columnName = (char **)SDDS_GetColumnNames(SDDS_dataset, &columns)))
1015 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1016 for (i = 0; i < columns; i++) {
1017 if (wild_match(columnName[i], "*Constraints*") && strcmp(columnName[i], "ConstraintsViolation") != 0) {
1018 data = SDDS_Realloc(data, sizeof(*data) * (constraints + 1));
1019 data[constraints] = NULL;
1020 if (!(data[constraints] = (double *)SDDS_GetColumnInDoubles(SDDS_dataset, columnName[i])))
1021 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1022 constraints++;
1023 }
1024 }
1025 if (constraints) {
1026 const_violation = calloc(rows, sizeof(*const_violation));
1027 for (i = 0; i < rows; i++) {
1028 for (j = 0; j < constraints; j++) {
1029 if (data[j][i] < 0)
1030 const_violation[i] += data[j][i];
1031 }
1032 }
1033 for (j = 0; j < constraints; j++)
1034 free(data[j]);
1035 free(data);
1036 }
1037 }
1038 return const_violation;
1039}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_SetDefaultIOBufferSize(int32_t newValue)
Definition SDDS_binary.c:82
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
Definition SDDS_copy.c:40
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:578
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int32_t SDDS_AssertRowFlags(SDDS_DATASET *SDDS_dataset, uint32_t mode,...)
Sets acceptance flags for rows based on specified criteria.
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
void * SDDS_GetInternalColumn(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves an internal pointer to the data of a specified column, including all rows.
void * SDDS_GetParameterByIndex(SDDS_DATASET *SDDS_dataset, int32_t index, void *memory)
Retrieves the value of a specified parameter by its index from the current data table of a data set.
double * SDDS_GetColumnInDoubles(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of doubles, considering only rows mark...
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:50
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_GotoPage(SDDS_DATASET *SDDS_dataset, int32_t page_number)
Sets the current page of the SDDS dataset to the specified page number.
int32_t SDDS_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
int32_t SDDS_DefineSimpleParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data parameter within the SDDS dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:421
int32_t SDDS_GetParameterType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a parameter in the SDDS dataset by its index.
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
int32_t SDDS_CheckColumn(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a column exists in the SDDS dataset with the specified name, units, and type.
char ** SDDS_GetColumnNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all columns in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:474
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:318
int32_t SDDS_GetTypeSize(int32_t type)
Retrieves the size in bytes of a specified SDDS data type.
int32_t SDDS_GetColumnType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a column in the SDDS dataset by its index.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:380
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:743
#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_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric type.
Definition SDDStypes.h:157
#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
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
Definition array.c:190
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:65
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int64_t * non_dominated_sort(population *new_pop)
Performs non-dominated sorting on a population and assigns ranks and crowding distances.
void fill_population(population *pop, long rows, long columns, double **columnValue, long *maximize, double *const_violation)
Initializes and fills the population structure with individuals and their objective values.
void free_pop_mem(population *pop)
Frees all dynamically allocated memory associated with a population.
long replaceFileAndBackUp(char *file, char *replacement)
Replaces a file with a replacement file and creates a backup of the original.
Definition replacefile.c:78
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:357
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:391
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:588
long scanItemList(unsigned long *flags, char **item, long *items, unsigned long mode,...)
Scans a list of items and assigns values based on provided keywords and types.
char * str_tolower(char *s)
Convert a string to lower case.
Definition str_tolower.c:27
int wild_match(char *string, char *template)
Determine whether one string is a wildcard match for another.
Definition wild_match.c:49
int strcmp_nh(const char *s1, const char *s2)
Compare two strings with a custom non-hierarchical ranking.
Definition wild_match.c:583