Skip to content

Commit 8d51651

Browse files
committed
Merge branch 'fix-2643' of https://github.com/ERGO-Code/HiGHS into fix-2643
2 parents e5fb885 + 92b72f4 commit 8d51651

File tree

177 files changed

+18646
-2320
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

177 files changed

+18646
-2320
lines changed

THIRD_PARTY_NOTICES.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Third Party Licenses and Acknowledgements
2+
3+
The majority of the HiGHS source code is available under the [MIT license](https://opensource.org/license/MIT).
4+
5+
Code in the `/extern` directory was originally developed by third-parties and is
6+
licensed under additional licenses.
7+
8+
## amd
9+
10+
The source code in `/extern/amd` is distributed under the [BSD-3 license](https://opensource.org/license/bsd-3-clause)
11+
at `/extern/amd/License.txt`.
12+
13+
It was originally developed by Timothy Davis.
14+
15+
The upstream source code is available at:
16+
17+
* https://github.com/DrTimothyAldenDavis/SuiteSparse
18+
19+
To avoid compiling this code into HiGHS, use `-DHIPO=OFF`.
20+
21+
## filereaderlp
22+
23+
The source code in `/extern/filereaderlp` is distributed under the [MIT license](https://opensource.org/license/MIT)
24+
at `/extern/filereaderlp/LICENSE`.
25+
26+
It was originally developed by Michael Feldmeier.
27+
28+
The upstream source code is available at:
29+
30+
* https://github.com/feldmeier/FilereaderLP
31+
32+
## metis
33+
34+
The source code in `/extern/metis` is distributed under the [Apache 2.0 license](https://opensource.org/license/apache-2-0)
35+
at `/extern/metis/LICENSE.txt`.
36+
37+
It was originally developed by George Karypis.
38+
39+
The upstream source code is available at:
40+
41+
* https://github.com/KarypisLab/METIS
42+
* https://github.com/KarypisLab/GKlib
43+
44+
To avoid compiling this code into HiGHS, use `-DHIPO=OFF`.
45+
46+
## pdqsort
47+
48+
The source code in `/extern/pdqsort` is distributed under the [zlib license](https://opensource.org/license/zlib)
49+
at `/extern/pdqsort/license.txt`.
50+
51+
It was originally developed by Orson Peters.
52+
53+
The upstream source code is available at:
54+
55+
* https://github.com/orlp/pdqsort
56+
57+
## rcm
58+
59+
The source code in `/extern/rcm` is distributed under the [MIT license](https://opensource.org/license/MIT)
60+
at `/extern/rcm/LICENSE`.
61+
62+
It was originally developed by Alan George, Joseph Liu, and John Burkardt.
63+
64+
The upstream source code is available at:
65+
66+
* https://people.sc.fsu.edu/~jburkardt/cpp_src/rcm/rcm.html
67+
68+
## zstr
69+
70+
The source code in `/extern/zstr` is distributed under the [MIT license](https://opensource.org/license/MIT)
71+
at `/extern/zstr/LICENSE`.
72+
73+
It was originally developed by Matei David.
74+
75+
The upstream source code is available at:
76+
77+
* https://github.com/mateidavid/zstr

check/TestCAPI.c

Lines changed: 107 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,31 @@ void assertLogical(const char* name, const HighsInt is) {
238238
}
239239
}
240240

241+
void createBlendingLp(void* highs) {
242+
// Special variant of the blending LP, with redundant constraint so
243+
// that LP is reduced by presolve - but not to empty!
244+
const double inf = Highs_getInfinity(highs);
245+
246+
HighsInt num_col = 2;
247+
HighsInt num_row = 3;
248+
HighsInt num_nz = 6;
249+
HighsInt sense = -1;
250+
double col_cost[2] = {8, 10};
251+
double col_lower[2] = {0, 0};
252+
double col_upper[2] = {inf, inf};
253+
double row_lower[3] = {-inf, -inf, -inf};
254+
double row_upper[3] = {500, 120, 210};
255+
HighsInt a_index[6] = {0, 1, 0, 1, 0, 1};
256+
double a_value[6] = {0.5, 0.5, 0.3, 0.5, 0.7, 0.5};
257+
HighsInt a_start[3] = {0, 2, 4};
258+
Highs_addVars(highs, num_col, col_lower, col_upper);
259+
Highs_changeColsCostByRange(highs, 0, num_col - 1, col_cost);
260+
Highs_addRows(highs, num_row, row_lower, row_upper, num_nz, a_start, a_index,
261+
a_value);
262+
Highs_changeObjectiveSense(highs, sense);
263+
}
264+
265+
// Test methods
241266
void versionApi() {
242267
if (dev_run) {
243268
printf("HiGHS version %s\n", Highs_version());
@@ -530,80 +555,28 @@ void minimalApiIllegalLp() {
530555
assert(model_status == kHighsModelStatusNotset);
531556
}
532557

533-
void fullApi() {
558+
void testNames() {
534559
void* highs = Highs_create();
535560

536561
if (!dev_run) Highs_setBoolOptionValue(highs, "output_flag", 0);
537562

538-
HighsInt num_col = 2;
539-
HighsInt num_row = 2;
540-
HighsInt num_nz = 4;
541-
HighsInt a_format = kHighsMatrixFormatRowwise;
542-
HighsInt sense = kHighsObjSenseMinimize;
543-
double offset = 0;
544-
double cc[2] = {1.0, -2.0};
545-
double cl[2] = {0.0, 0.0};
546-
double cu[2] = {10.0, 10.0};
547-
double rl[2] = {0.0, 0.0};
548-
double ru[2] = {2.0, 1.0};
549-
HighsInt a_start[3] = {0, 2, 4};
550-
HighsInt a_index[4] = {0, 1, 0, 1};
551-
double a_value[4] = {1.0, 2.0, 1.0, 3.0};
552-
553-
assert(Highs_addCols(highs, 2, cc, cl, cu, 0, NULL, NULL, NULL) == 0);
554-
assert(Highs_addRows(highs, 2, rl, ru, 4, a_start, a_index, a_value) == 0);
563+
createBlendingLp(highs);
555564

556-
assert(Highs_getNumCols(highs) == num_col);
557-
assert(Highs_getNumRows(highs) == num_row);
558-
assert(Highs_getNumNz(highs) == num_nz);
559-
assert(Highs_getHessianNumNz(highs) == 0);
560-
561-
HighsInt ck_num_col;
562-
HighsInt ck_num_row;
563-
HighsInt ck_num_nz;
564-
HighsInt ck_sense;
565-
double ck_offset;
566-
double ck_cc[2];
567-
double ck_cl[2];
568-
double ck_cu[2];
569-
double ck_rl[2];
570-
double ck_ru[2];
571-
HighsInt ck_a_start[3];
572-
HighsInt ck_a_index[4];
573-
double ck_a_value[4];
574565
HighsInt return_status;
575-
return_status = Highs_getModel(
576-
highs, a_format, 0, &ck_num_col, &ck_num_row, &ck_num_nz, NULL, &ck_sense,
577-
&ck_offset, ck_cc, ck_cl, ck_cu, ck_rl, ck_ru, ck_a_start, ck_a_index,
578-
ck_a_value, NULL, NULL, NULL, NULL);
579-
assert(return_status == kHighsStatusOk);
580566

581-
assert(ck_num_col == num_col);
582-
assert(ck_num_row == num_row);
583-
assert(ck_num_nz == num_nz);
584-
assert(ck_sense == sense);
585-
assert(ck_offset == offset);
586-
assert(doubleArraysEqual(num_col, ck_cc, cc));
587-
assert(doubleArraysEqual(num_col, ck_cl, cl));
588-
assert(doubleArraysEqual(num_col, ck_cu, cu));
589-
assert(doubleArraysEqual(num_row, ck_rl, rl));
590-
assert(doubleArraysEqual(num_row, ck_ru, ru));
591-
assert(highsIntArraysEqual(num_col, ck_a_start, a_start));
592-
assert(highsIntArraysEqual(num_nz, ck_a_index, a_index));
593-
assert(doubleArraysEqual(num_nz, ck_a_value, a_value));
594-
595-
return_status = Highs_run(highs);
596-
assert(return_status == kHighsStatusOk);
567+
HighsInt num_col = Highs_getNumCols(highs);
568+
HighsInt num_row = Highs_getNumRows(highs);
597569

598570
char* col_prefix = "Col";
599571
char* row_prefix = "Row";
600572
// Check index out of bounds
573+
601574
return_status = Highs_passColName(highs, -1, col_prefix);
602575
assert(return_status == kHighsStatusError);
603-
return_status = Highs_passColName(highs, num_col, col_prefix);
604-
assert(return_status == kHighsStatusError);
605576
return_status = Highs_passRowName(highs, -1, row_prefix);
606577
assert(return_status == kHighsStatusError);
578+
return_status = Highs_passColName(highs, num_col, col_prefix);
579+
assert(return_status == kHighsStatusError);
607580
return_status = Highs_passRowName(highs, num_row, row_prefix);
608581
assert(return_status == kHighsStatusError);
609582

@@ -615,12 +588,12 @@ void fullApi() {
615588
return_status = Highs_writeModel(highs, "");
616589
assert(return_status == kHighsStatusError);
617590

591+
char name[5]; // 3 chars prefix, 1 char iCol, 1 char 0-terminator
592+
618593
// Define all column names to be different
619594
for (HighsInt iCol = 0; iCol < num_col; iCol++) {
620-
char name[5]; // 3 chars prefix, 1 char iCol, 1 char 0-terminator
621595
sprintf(name, "%s%" HIGHSINT_FORMAT "", col_prefix, iCol);
622-
const char* name_p = name;
623-
return_status = Highs_passColName(highs, iCol, name_p);
596+
return_status = Highs_passColName(highs, iCol, name);
624597
assert(return_status == kHighsStatusOk);
625598
}
626599
return_status = Highs_writeModel(highs, "");
@@ -629,7 +602,6 @@ void fullApi() {
629602
// Check that the columns can be found by name
630603
HighsInt ck_iCol;
631604
for (HighsInt iCol = 0; iCol < num_col; iCol++) {
632-
char name[5];
633605
return_status = Highs_getColName(highs, iCol, name);
634606
assert(return_status == kHighsStatusOk);
635607
return_status = Highs_getColByName(highs, name, &ck_iCol);
@@ -649,10 +621,8 @@ void fullApi() {
649621

650622
// Define all row names to be different
651623
for (HighsInt iRow = 0; iRow < num_row; iRow++) {
652-
char name[5]; // 3 chars prefix, 1 char iCol, 1 char 0-terminator
653624
sprintf(name, "%s%" HIGHSINT_FORMAT "", row_prefix, iRow);
654-
const char* name_p = name;
655-
return_status = Highs_passRowName(highs, iRow, name_p);
625+
return_status = Highs_passRowName(highs, iRow, name);
656626
assert(return_status == kHighsStatusOk);
657627
}
658628
return_status = Highs_writeModel(highs, "");
@@ -672,21 +642,52 @@ void fullApi() {
672642
assert(return_status == kHighsStatusError);
673643

674644
for (HighsInt iCol = 0; iCol < num_col; iCol++) {
675-
char name[5];
676-
char* name_p = name;
677-
return_status = Highs_getColName(highs, iCol, name_p);
645+
return_status = Highs_getColName(highs, iCol, name);
678646
assert(return_status == kHighsStatusOk);
679647
if (dev_run)
680-
printf("Column %" HIGHSINT_FORMAT " has name %s\n", iCol, name_p);
648+
printf("Column %" HIGHSINT_FORMAT " has name %s\n", iCol, name);
681649
}
682650

683651
for (HighsInt iRow = 0; iRow < num_row; iRow++) {
684-
char name[5];
685-
char* name_p = name;
686-
return_status = Highs_getRowName(highs, iRow, name_p);
652+
return_status = Highs_getRowName(highs, iRow, name);
687653
assert(return_status == kHighsStatusOk);
688654
if (dev_run)
689-
printf("Row %" HIGHSINT_FORMAT " has name %s\n", iRow, name_p);
655+
printf("Row %" HIGHSINT_FORMAT " has name %s\n", iRow, name);
656+
}
657+
658+
// Check extraction of names for the presolved LP, in which the
659+
// first row is removed
660+
Highs_presolve(highs);
661+
if (dev_run) Highs_writePresolvedModel(highs, "");
662+
663+
HighsInt presolved_num_col = Highs_getPresolvedNumCol(highs);
664+
HighsInt presolved_num_row = Highs_getPresolvedNumRow(highs);
665+
assert(presolved_num_col == num_col);
666+
assert(presolved_num_row == num_row-1);
667+
668+
char presolved_name[5];
669+
670+
return_status = Highs_getPresolvedColName(highs, -1, presolved_name);
671+
assert(return_status == kHighsStatusError);
672+
return_status = Highs_getPresolvedRowName(highs, -1, presolved_name);
673+
assert(return_status == kHighsStatusError);
674+
return_status = Highs_getPresolvedColName(highs, presolved_num_col, presolved_name);
675+
assert(return_status == kHighsStatusError);
676+
return_status = Highs_getPresolvedRowName(highs, presolved_num_row, presolved_name);
677+
assert(return_status == kHighsStatusError);
678+
679+
for (HighsInt iCol = 0; iCol < presolved_num_col; iCol++) {
680+
return_status = Highs_getPresolvedColName(highs, iCol, presolved_name);
681+
assert(return_status == kHighsStatusOk);
682+
if (dev_run)
683+
printf("Presolved column %" HIGHSINT_FORMAT " has name %s\n", iCol, presolved_name);
684+
}
685+
686+
for (HighsInt iRow = 0; iRow < presolved_num_row; iRow++) {
687+
return_status = Highs_getPresolvedRowName(highs, iRow, presolved_name);
688+
assert(return_status == kHighsStatusOk);
689+
if (dev_run)
690+
printf("Presolved row %" HIGHSINT_FORMAT " has name %s\n", iRow, presolved_name);
690691
}
691692

692693
Highs_destroy(highs);
@@ -1799,18 +1800,25 @@ void testGetModel() {
17991800
Highs_addRows(highs, num_row, row_lower, row_upper, num_nz, a_start, a_index,
18001801
a_value);
18011802
Highs_changeObjectiveSense(highs, sense);
1802-
Highs_run(highs);
1803+
1804+
assert(Highs_getNumCols(highs) == num_col);
1805+
assert(Highs_getNumRows(highs) == num_row);
1806+
assert(Highs_getNumNz(highs) == num_nz);
1807+
assert(Highs_getHessianNumNz(highs) == 0);
18031808

18041809
HighsInt ck_num_col;
18051810
HighsInt ck_num_row;
18061811
HighsInt ck_num_nz;
18071812
HighsInt ck_sense;
18081813
double ck_offset;
1814+
HighsInt a_format = kHighsMatrixFormatRowwise;
18091815

18101816
// Get the model dimensions by passing array pointers as NULL
1811-
Highs_getLp(highs, kHighsMatrixFormatRowwise, &ck_num_col, &ck_num_row,
1817+
HighsInt return_status;
1818+
return_status = Highs_getLp(highs, a_format, &ck_num_col, &ck_num_row,
18121819
&ck_num_nz, &ck_sense, &ck_offset, NULL, NULL, NULL, NULL, NULL,
18131820
NULL, NULL, NULL, NULL);
1821+
assert(return_status == kHighsStatusOk);
18141822

18151823
assert(ck_num_col == num_col);
18161824
assert(ck_num_row == num_row);
@@ -1829,11 +1837,32 @@ void testGetModel() {
18291837
double* ck_a_value = (double*)malloc(sizeof(double) * num_nz);
18301838

18311839
// Get the arrays
1832-
Highs_getLp(highs, kHighsMatrixFormatRowwise, &ck_num_col, &ck_num_row,
1840+
return_status = Highs_getLp(highs, a_format, &ck_num_col, &ck_num_row,
18331841
&ck_num_nz, &ck_sense, &ck_offset, ck_col_cost, ck_col_lower,
18341842
ck_col_upper, ck_row_lower, ck_row_upper, ck_a_start, ck_a_index,
18351843
ck_a_value, NULL);
1844+
assert(return_status == kHighsStatusOk);
1845+
1846+
assert(doubleArraysEqual(num_col, ck_col_cost, col_cost));
1847+
assert(doubleArraysEqual(num_col, ck_col_lower, col_lower));
1848+
assert(doubleArraysEqual(num_col, ck_col_upper, col_upper));
1849+
assert(doubleArraysEqual(num_row, ck_row_lower, row_lower));
1850+
assert(doubleArraysEqual(num_row, ck_row_upper, row_upper));
1851+
assert(highsIntArraysEqual(num_col, ck_a_start, a_start));
1852+
assert(highsIntArraysEqual(num_nz, ck_a_index, a_index));
1853+
assert(doubleArraysEqual(num_nz, ck_a_value, a_value));
18361854

1855+
return_status = Highs_getModel(
1856+
highs, a_format, 0, &ck_num_col, &ck_num_row, &ck_num_nz, NULL, &ck_sense,
1857+
&ck_offset, ck_col_cost, ck_col_lower,
1858+
ck_col_upper, ck_row_lower, ck_row_upper, ck_a_start, ck_a_index,
1859+
ck_a_value, NULL, NULL, NULL, NULL);
1860+
assert(return_status == kHighsStatusOk);
1861+
1862+
assert(ck_num_col == num_col);
1863+
assert(ck_num_row == num_row);
1864+
assert(ck_num_nz == num_nz);
1865+
assert(ck_sense == sense);
18371866
assert(doubleArraysEqual(num_col, ck_col_cost, col_cost));
18381867
assert(doubleArraysEqual(num_col, ck_col_lower, col_lower));
18391868
assert(doubleArraysEqual(num_col, ck_col_upper, col_upper));
@@ -2458,7 +2487,6 @@ int main() {
24582487
minimalApiIllegalLp();
24592488
testCallback();
24602489
versionApi();
2461-
fullApi();
24622490
minimalApiLp();
24632491
minimalApiMip();
24642492
minimalApiQp();
@@ -2472,6 +2500,7 @@ int main() {
24722500
testPassHessian();
24732501
testRanging();
24742502
testFeasibilityRelaxation();
2503+
testNames();
24752504
testGetModel();
24762505
testMultiObjective();
24772506
testQpIndefiniteFailure();

0 commit comments

Comments
 (0)