56#include "non_dominated_sort.h"
62# include <sys/types.h>
75 SET_NON_DOMINATE_SORT,
81char *option[N_OPTIONS] = {
95 "sddssort [<SDDSinput>] [<SDDSoutput>]\n"
96 " [-pipe=[input][,output]]\n"
97 " [-column=<name>[,{increasing|decreasing}|{minimize|maximize}][,absolute]...] \n"
98 " [-unique[=count]]\n"
100 " [-parameter=<name>[,{increasing|decreasing}]...]\n"
102 " [-nonDominateSort] \n"
103 " [-hypervolume=<ref1>,<ref2>,...] \n"
104 " [-majorOrder=row|column]\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"
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"
117 " Suppress warning messages.\n\n"
118 " -parameter=<name>[,{increasing|decreasing}]...\n"
119 " Specify parameters to sort by.\n\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"
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";
141 short decreasing_order, maximize_order, absolute;
144 int32_t element_size;
147static char *order_mode[5] = {
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);
159 SORT_REQUEST *xsort_parameter,
long xsort_parameters,
long uniqueRows,
long provideIdenticalCount,
160 long pipeFlags,
long non_dominate_sort);
162double *read_constr_violation(
SDDS_DATASET *SDDS_dataset);
164long numericHigh = 0, constDefined = 0;
166static long hypervolume_flag = 0;
167static long hv_nref = 0;
168static double *hv_reference = NULL;
170int main(
int argc,
char **argv) {
172 char *input, *output;
173 long i_arg, non_dominate_sort = 0;
176 long tmpfile_used, sort_requests, noWarnings, uniqueRows, provideIdenticalCount, tmpfileForInternalPipe;
177 long sort_parameters;
179 unsigned long pipeFlags, majorOrderFlag;
180 short columnMajorOrder = -1;
183 argc =
scanargs(&s_arg, argc, argv);
188 input = output = NULL;
189 tmpfile_used = sort_requests = noWarnings = sort_parameters = tmpfileForInternalPipe = 0;
190 sort_request = sort_parameter = NULL;
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:
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;
209 case SET_NON_DOMINATE_SORT:
210 non_dominate_sort = 1;
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);
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");
226 if (s_arg[i_arg].n_items < 2 || s_arg[i_arg].n_items > 4)
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) {
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)) {
240 sort_request[sort_requests].decreasing_order = 1;
245 sort_request[sort_requests].maximize_order = 1;
248 sort_request[sort_requests].absolute = 1;
251 fprintf(stderr,
"unknown sort order specified--give 'increasing' or 'decreasing' for dominated sorting\n or'maximize' or 'minimize' for non-dominated-sorting.\n");
260 if (s_arg[i_arg].n_items < 2 || s_arg[i_arg].n_items > 3)
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'");
268 sort_parameter[sort_parameters].decreasing_order = 0;
274 case SET_NUMERICHIGH:
278 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
283 if (s_arg[i_arg].n_items > 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)
288 provideIdenticalCount = 1;
292 fprintf(stderr,
"error: unknown switch: %s\n", s_arg[i_arg].list[0]);
298 input = s_arg[i_arg].list[0];
299 else if (output == NULL)
300 output = s_arg[i_arg].list[0];
306 if (!sort_requests && !sort_parameters)
308 processFilenames(
"sddssort", &input, &output, pipeFlags, noWarnings, &tmpfile_used);
313 if (sort_requests <= 1)
314 non_dominate_sort = 0;
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");
323 if (SDDS_input.layout.popenUsed) {
328 char tmpfileName[1024];
330 sprintf(tmpfileName,
"/tmp/sddssort.%ld", (
long)pid);
331 tmpfileForInternalPipe = 1;
336 if (columnMajorOrder != -1)
337 SDDS_tmp.layout.data_mode.column_major = columnMajorOrder;
339 SDDS_tmp.layout.data_mode.column_major = SDDS_input.layout.data_mode.column_major;
340 if (non_dominate_sort) {
376 if (columnMajorOrder != -1)
377 SDDS_output.layout.data_mode.column_major = columnMajorOrder;
379 SDDS_output.layout.data_mode.column_major = SDDS_input.layout.data_mode.column_major;
380 if (provideIdenticalCount &&
385 if (non_dominate_sort) {
396 if (hypervolume_flag &&
402 if (!SDDS_SortAll(&SDDS_input, &SDDS_output, sort_request, sort_requests, sort_parameter, sort_parameters,
403 uniqueRows, provideIdenticalCount, pipeFlags, non_dominate_sort)) {
421static long sort_requests;
422static int64_t *sort_row_index;
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;
432 uint64_t magnitude1, magnitude2;
439 ldouble1 = *(
long double *)data1;
440 ldouble2 = *(
long double *)data2;
442 return isnan(ldouble2) ? 0 : 1;
445 return ldouble1 > ldouble2 ? 1 : (ldouble1 < ldouble2 ? -1 : 0);
447 double1 = *(
double *)data1;
448 double2 = *(
double *)data2;
450 return isnan(double2) ? 0 : 1;
453 return double1 > double2 ? 1 : (double1 < double2 ? -1 : 0);
455 float1 = *(
float *)data1;
456 float2 = *(
float *)data2;
458 return isnan(float2) ? 0 : 1;
461 return float1 > float2 ? 1 : (float1 < float2 ? -1 : 0);
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);
467 long1 = *(int32_t *)data1;
468 long2 = *(int32_t *)data2;
469 return long1 > long2 ? 1 : (long1 < long2 ? -1 : 0);
471 short1 = *(
short *)data1;
472 short2 = *(
short *)data2;
473 return short1 > short2 ? 1 : (short1 < short2 ? -1 : 0);
475 if (*(uint64_t *)data1 > *(uint64_t *)data2)
477 if (*(uint64_t *)data1 < *(uint64_t *)data2)
481 if (*(uint32_t *)data1 > *(uint32_t *)data2)
483 if (*(uint32_t *)data1 < *(uint32_t *)data2)
487 if (*(
unsigned short *)data1 > *(
unsigned short *)data2)
489 if (*(
unsigned short *)data1 < *(
unsigned short *)data2)
493 char1 = *(
char *)data1;
494 char2 = *(
char *)data2;
495 return char1 > char2 ? 1 : (char1 < char2 ? -1 : 0);
498 return (
strcmp_nh(*(
char **)data1, *(
char **)data2));
500 return (strcmp(*(
char **)data1, *(
char **)data2));
502 SDDS_SetError(
"Problem doing data comparison--invalid data type (SDDS_CompareData)");
509 ldouble1 = fabsl(*(
long double *)data1);
510 ldouble2 = fabsl(*(
long double *)data2);
512 return isnan(ldouble2) ? 0 : 1;
515 return ldouble1 > ldouble2 ? 1 : (ldouble1 < ldouble2 ? -1 : 0);
517 double1 = fabs(*(
double *)data1);
518 double2 = fabs(*(
double *)data2);
520 return isnan(double2) ? 0 : 1;
523 return double1 > double2 ? 1 : (double1 < double2 ? -1 : 0);
525 float1 = fabsf(*(
float *)data1);
526 float2 = fabsf(*(
float *)data2);
528 return isnan(float2) ? 0 : 1;
531 return float1 > float2 ? 1 : (float1 < float2 ? -1 : 0);
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);
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);
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);
551 if (*(uint64_t *)data1 > *(uint64_t *)data2)
553 if (*(uint64_t *)data1 < *(uint64_t *)data2)
557 if (*(uint32_t *)data1 > *(uint32_t *)data2)
559 if (*(uint32_t *)data1 < *(uint32_t *)data2)
563 if (*(
unsigned short *)data1 > *(
unsigned short *)data2)
565 if (*(
unsigned short *)data1 < *(
unsigned short *)data2)
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);
576 return (
strcmp_nh(*(
char **)data1, *(
char **)data2));
578 return (strcmp(*(
char **)data1, *(
char **)data2));
580 SDDS_SetError(
"Problem doing data comparison--invalid data type (SDDS_CompareData)");
587int SDDS_CompareRows(
const void *vrow1,
const void *vrow2) {
592 row1 = *(int64_t *)vrow1;
593 row2 = *(int64_t *)vrow2;
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,
600 return (sort_request[i].decreasing_order ? -comparison : comparison);
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];
611 data = SDDS_dataset->data;
613 fprintf(stderr,
"swapping row %" PRId64
" with row %" PRId64
"\n", row1, row2);
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)");
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));
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);
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;
635 double **data = NULL, *dist = NULL, *const_violation = NULL;
636 int32_t *rank = NULL;
638 long *maximize = NULL;
641 SDDS_sort = SDDS_dataset;
642 sort_request = xsort_request;
643 sort_requests = xsort_requests;
647 for (i = 0; i < sort_requests; i++) {
649 sprintf(s,
"column name \"%s\" is not recognized(SDDS_GetColumnIndex)", sort_request[i].name);
656 if (sort_request[i].element_size <= 0 ||
658 SDDS_SetError(
"Problem getting internal column data for sort (SDDS_SortRows)");
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++) {
667 fprintf(stderr,
"Non-dominated sort is not available for string column.\n");
675 maximize[i] = sort_request[i].maximize_order;
677 const_violation = read_constr_violation(SDDS_sort);
678 fill_population(&pop, rows, sort_requests, data, maximize, const_violation);
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;
689 if (hypervolume_flag) {
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);
699 for (i = 0; i < sort_requests; i++)
704 sort_row_index =
tmalloc(
sizeof(*sort_row_index) * rows);
705 for (i = 0; i < rows; i++)
706 sort_row_index[i] = i;
710 qsort((
void *)sort_row_index, rows,
sizeof(*sort_row_index), SDDS_CompareRows);
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");
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) {
728 if (!SDDS_SwapRows(SDDS_sort, i, j)) {
729 SDDS_SetError(
"Problem swapping rows after index sort (SDDS_SortRows");
734 sort_row_index[i] = i;
737 sort_row_index[k] = j;
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");
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) {
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)) {
764 free(sort_row_index);
769long SDDS_UnsetDuplicateRows(
SDDS_DATASET *SDDS_dataset,
SORT_REQUEST *xsort_request,
long xsort_requests,
long provideIdenticalCount) {
771 int64_t *identicalCount;
775 SDDS_sort = SDDS_dataset;
776 sort_request = xsort_request;
777 sort_requests = xsort_requests;
779 for (i = 0; i < sort_requests; i++) {
781 sprintf(s,
"column name \"%s\" is not recognized(SDDS_GetColumnIndex)", sort_request[i].name);
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;
797 for (i = 0; i < rows - 1; i++) {
800 for (j = i + 1; j < rows; j++) {
802 if (SDDS_CompareRows(&i, &j) == 0) {
803 identicalCount[i] += 1;
812 free(identicalCount);
815 if (provideIdenticalCount && !
SDDS_SetColumn(SDDS_sort, SDDS_SET_BY_NAME, identicalCount, rows,
"IdenticalCount")) {
817 free(identicalCount);
821 free(identicalCount);
826static long sort_parameters;
829int SDDS_ComparePages(
const void *vpage1,
const void *vpage2) {
833 static int32_t page1, page2;
837 page1 = *(int32_t *)vpage1;
838 page2 = *(int32_t *)vpage2;
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])))) {
847 return (sort_parameter[i].decreasing_order ? -comparison : comparison);
858 long xsort_requests,
SORT_REQUEST *xsort_parameter,
long xsort_parameters,
long uniqueRows,
859 long provideIdenticalCount,
long xpipeFlags,
long non_dominate_sort) {
861 int32_t *xsort_page_index;
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++) {
875 sprintf(s,
"Unable to get parameter value--parameter name \"%s\" is not recognized(SDDS_GetParameterIndex)", sort_parameter[i].name);
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;
888 if (xpipeFlags || SDDS_sortpage->layout.gzipFile) {
891 tmp_datasets = realloc(tmp_datasets,
sizeof(*tmp_datasets) * (pages + 1));
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));
905 SDDS_SetError(
"Problem getting parameter value for sort (SDDS_SortAll)");
913 xsort_page_index =
tmalloc(
sizeof(*xsort_page_index) * pages);
914 for (k = 0; k < pages; k++)
915 xsort_page_index[k] = k;
917 qsort((
void *)xsort_page_index, pages,
sizeof(*xsort_page_index), SDDS_ComparePages);
920 for (i = 0; i < pages; i++) {
921 j = xsort_page_index[i];
922 if (xpipeFlags || SDDS_sortpage->layout.gzipFile) {
952 if (!SDDS_SortRows(SDDS_outputx, sort_request, sort_requests, non_dominate_sort)) {
957 if (uniqueRows && !SDDS_UnsetDuplicateRows(SDDS_outputx, sort_request, sort_requests, provideIdenticalCount)) {
978 if (!SDDS_SortRows(SDDS_outputx, sort_request, sort_requests, non_dominate_sort)) {
983 if (uniqueRows && !SDDS_UnsetDuplicateRows(SDDS_outputx, sort_request, sort_requests, provideIdenticalCount)) {
998 if (xsort_page_index)
999 free(xsort_page_index);
1003double *read_constr_violation(
SDDS_DATASET *SDDS_dataset) {
1004 double *const_violation = NULL, **data = NULL;
1005 int32_t columns, constraints, j;
1007 char **columnName = NULL;
1009 columns = constraints = 0;
1011 if (!constDefined && !(const_violation = (
double *)
SDDS_GetColumnInDoubles(SDDS_dataset,
"ConstraintsViolation")))
1012 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
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;
1021 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1026 const_violation = calloc(rows,
sizeof(*const_violation));
1027 for (i = 0; i < rows; i++) {
1028 for (j = 0; j < constraints; j++) {
1030 const_violation[i] += data[j][i];
1033 for (j = 0; j < constraints; j++)
1038 return const_violation;
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_SetDefaultIOBufferSize(int32_t newValue)
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
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_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.
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.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
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.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
#define SDDS_ULONG
Identifier for the unsigned 32-bit integer data type.
#define SDDS_FLOAT
Identifier for the float data type.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_ULONG64
Identifier for the unsigned 64-bit integer data type.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
#define SDDS_SHORT
Identifier for the signed short integer data type.
#define SDDS_CHARACTER
Identifier for the character data type.
#define SDDS_USHORT
Identifier for the unsigned short integer data type.
#define SDDS_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric type.
#define SDDS_DOUBLE
Identifier for the double data type.
#define SDDS_LONGDOUBLE
Identifier for the long double data type.
#define SDDS_LONG64
Identifier for the signed 64-bit integer data type.
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
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.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
long processPipeOption(char **item, long items, unsigned long *flags)
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
void free_scanargs(SCANNED_ARG **scanned, int argc)
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.
int wild_match(char *string, char *template)
Determine whether one string is a wildcard match for another.
int strcmp_nh(const char *s1, const char *s2)
Compare two strings with a custom non-hierarchical ranking.