Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ set_tests_properties(applications-${EXECUTABLE_NAME}-build
#
set(instances
example_small.dat-s
example_small_multiLP.dat-s
example_small_cbf.cbf
example_inf.dat-s
example_TT.dat-s.gz
Expand Down
36 changes: 36 additions & 0 deletions instances/example_small_multiLP.dat-s
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
3 = number of variables
4 = number of blocks
2 -4 2 -4 = blocksizes (negative sign for LP-block, size of LP-block equals the number of LP-constraints)
* the next line gives the objective values in the order of the variables
1 -2 -1
* the remaining lines give the nonzeroes of the constraints with variable (0 meaning the constant part) block row column value
1 1 1 1 1 * first variable in block one, row one, column one has coefficient one
2 1 1 2 1 * variable two in block one, row one, column two has coefficient one (note that because we expect the matrix to be symmetric, we don't need to give the entry for row two and column one)
3 1 2 2 1
1 3 1 2 1
3 3 1 1 1
0 3 2 2 -2.1 * the constant part (variable zero) in block two, row two, column two equals -2.1 (which we are substracting from the A_i, so in the combined matrix it will have a positive sign)
1 2 1 1 1 * block three is the LP block, the LP constraints appear as diagonal entries in this block
2 2 1 1 1
3 2 1 1 1
0 2 1 1 1
1 2 2 2 -1
2 2 2 2 -1
3 2 2 2 -1
0 2 2 2 -8
1 2 3 3 1
0 2 3 3 -10
1 2 4 4 -1
0 2 4 4 -10
2 4 1 1 1
0 4 1 1 -10
2 4 2 2 -1
0 4 2 2 -10
3 4 3 3 1
0 4 3 3 -10
3 4 4 4 -1
0 4 4 4 -10
*INTEGER
*1
*2
*3
107 changes: 56 additions & 51 deletions src/scipsdp/reader_sdpa.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ struct SDPA_Data
int nconsblocks; /**< number of constraint blocks specified in the input file */
int* sdpmemsize; /**< size of memory allocated for the nonconstant part of each SDP constraint */
int* sdpconstmemsize; /**< size of memory allocated for the constant part of each SDP constraint */
int idxlinconsblock; /**< the index of the linear constraint block */
int* blockoffsets; /**< row and columns offsets for merged LP blocks (0 for SDP blocks) */
int* newblockidx; /**< mapping of file block index to new internal index, skipping LP blocks */
char* buffer; /**< input buffer */
int bufferlen; /**< length of buffer */
};
Expand Down Expand Up @@ -483,6 +484,8 @@ SCIP_RETCODE SDPAfreeData(
SCIPfreeBlockMemoryArrayNull(scip, &data->createdconss, data->nlinconss);
SCIPfreeBlockMemoryArrayNull(scip, &data->sdpblockrank1, data->nsdpblocks);
SCIPfreeBlockMemoryArrayNull(scip, &data->sdpblocksizes, data->nsdpblocks);
SCIPfreeBlockMemoryArrayNull(scip, &data->blockoffsets, data->nconsblocks);
SCIPfreeBlockMemoryArrayNull(scip, &data->newblockidx, data->nconsblocks);
SCIPfreeBlockMemoryArrayNull(scip, &data->createdvars, data->nvars);

SCIPfreeBufferNull(scip, &data);
Expand Down Expand Up @@ -632,6 +635,7 @@ SCIP_RETCODE SDPAreadBlockSize(
int* blocksizes;
int nsdpblocks = 0;
int nblocks;
int lpoffset = 0; /* accumulator for the offset of the next lp-block */
int cnt = 0;
int b;
int c;
Expand All @@ -644,6 +648,9 @@ SCIP_RETCODE SDPAreadBlockSize(
SCIP_CALL( SCIPallocBufferArray(scip, &blocksizes, data->nconsblocks) );
SCIP_CALL( SCIPallocBufferArray(scip, &sdpblocksizes, data->nconsblocks) );

SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->blockoffsets), data->nconsblocks) );
SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(data->newblockidx), data->nconsblocks) );

assert( scip != NULL );
assert( file != NULL );
assert( linecount != NULL );
Expand All @@ -667,15 +674,10 @@ SCIP_RETCODE SDPAreadBlockSize(
/* if the entry is less than zero it describes the LP blocks */
if ( *(blocksizes + i) < 0 )
{
if ( data->idxlinconsblock == -1 )
data->idxlinconsblock = i;
else
{
SCIPerrorMessage("Only one LP block can be defined in line %" SCIP_LONGINT_FORMAT
" but at least two blocksizes are negative.\n", *linecount);
goto TERMINATE;
}
data->nlinconss = - *(blocksizes + i);
data->nlinconss += - *(blocksizes + i);
data->newblockidx[i] = -1;
data->blockoffsets[i] = lpoffset;
lpoffset += - *(blocksizes + i);
}
else
{
Expand All @@ -685,13 +687,15 @@ SCIP_RETCODE SDPAreadBlockSize(
*linecount);
goto TERMINATE;
}
data->newblockidx[i] = nsdpblocks;
data->blockoffsets[i] = 0;
*(sdpblocksizes + nsdpblocks) = *(blocksizes + i);
++nsdpblocks;
}
}

assert( data->idxlinconsblock < 0 || data->nlinconss > 0 );
assert( data->idxlinconsblock >= 0 || data->nlinconss == 0 );
assert( lpoffset == 0 || data->nlinconss > 0 );
assert( lpoffset > 0 || data->nlinconss == 0 );

if ( data->nlinconss < 0 )
{
Expand Down Expand Up @@ -765,6 +769,7 @@ SCIP_RETCODE SDPAreadObjVals(
SDPA_DATA* data /**< data pointer to save the results in */
)
{ /*lint --e{818}*/
SCIP_RETCODE retcode;
SCIP_Real* objvals;
int v;
int nreadvals;
Expand All @@ -785,9 +790,8 @@ SCIP_RETCODE SDPAreadObjVals(
}
assert( data->nvars >= 0 );

SCIP_CALL( readLineDoubles(scip, file, &data->buffer, &data->bufferlen, linecount, data->nvars, objvals, &nreadvals) );

if ( nreadvals == -1 )
retcode = readLineDoubles(scip, file, &data->buffer, &data->bufferlen, linecount, data->nvars, objvals, &nreadvals);
if ( retcode == SCIP_READERROR || nreadvals == -1 )
goto TERMINATE;
else if ( nreadvals != data->nvars )
{
Expand Down Expand Up @@ -865,9 +869,10 @@ SCIP_RETCODE SDPAreadBlocks(
int emptysdpblocks = 0;
int emptylinconsblocks = 0;
int nindcons = 0;
int blockidxoffset = 0;
int row;
int col;
int file_b; /* block index of file */
int file_row; /* row index of file */
int b; /* current block */
int v; /* current variable */
int c; /* current linear constraint */
Expand Down Expand Up @@ -977,23 +982,26 @@ SCIP_RETCODE SDPAreadBlocks(
}

/* switch from SDPA counting (starting from 1) to SCIP counting (starting from 0) */
file_b = b; /* the original block index of error messages */
file_row = row;
--v;
--b;
--row;
--col;

/* reset LP block offset */
blockidxoffset = 0;
if ( b < 0 || b >= data->nconsblocks )
{
SCIPerrorMessage("Given coefficient in line %" SCIP_LONGINT_FORMAT " for block %d which does not exist!\n",
*linecount, file_b);
goto TERMINATE;
}
assert( 0 <= b && b < data->nconsblocks );

/* check if this entry belongs to the LP block (FALSE) or to an SDP block (TRUE)*/
if ( b != data->idxlinconsblock )
/* check if this entry belongs to an LP block (FALSE) or to an SDP block (TRUE) */
if ( data->newblockidx[b] >= 0 )
{
/* check if the LP block was already read and adjust the counter as well as the offset for error messages */
if ( b > data->idxlinconsblock && data->idxlinconsblock >= 0 )
{
--b;
blockidxoffset = 1;
}
b = data->newblockidx[b];

if ( v < - 1 || v >= data->nvars )
{
Expand All @@ -1005,7 +1013,7 @@ SCIP_RETCODE SDPAreadBlocks(
if ( b < 0 || b >= data->nsdpblocks )
{
SCIPerrorMessage("Given coefficient in line %" SCIP_LONGINT_FORMAT " for SDP block %d which does not exist!\n",
*linecount, b + 1 + blockidxoffset);
*linecount, file_b);
goto TERMINATE;
}
assert( 0 <= b && b < data->nsdpblocks );
Expand Down Expand Up @@ -1106,7 +1114,7 @@ SCIP_RETCODE SDPAreadBlocks(
if ( SCIPisInfinity(scip, val) || SCIPisInfinity(scip, -val) )
{
SCIPerrorMessage("Given constant part in line %" SCIP_LONGINT_FORMAT " of block %d is infinity, which is not allowed.\n",
*linecount, b+1);
*linecount, file_b);
goto TERMINATE;
}

Expand Down Expand Up @@ -1144,6 +1152,9 @@ SCIP_RETCODE SDPAreadBlocks(
}
else /* LP block */
{
/* add the row/column offset for this block */
row += data->blockoffsets[b];
col += data->blockoffsets[b];
/* indicator variables have a negative variable index */
if ( v >= data->nvars )
{
Expand All @@ -1165,7 +1176,7 @@ SCIP_RETCODE SDPAreadBlocks(
if ( row < 0 || row >= data->nlinconss )
{
SCIPerrorMessage("Given linear coefficient in line %" SCIP_LONGINT_FORMAT " for linear constraint %d which does not exist!\n",
*linecount, row + 1);
*linecount, file_row);
goto TERMINATE;
}

Expand Down Expand Up @@ -1254,7 +1265,7 @@ SCIP_RETCODE SDPAreadBlocks(
if ( SCIPisInfinity(scip, val) || SCIPisInfinity(scip, -val))
{
SCIPerrorMessage("Given constant part in line %" SCIP_LONGINT_FORMAT " of block %d is infinity, which is not allowed.\n",
*linecount, b+1);
*linecount, file_b);
goto TERMINATE;
}

Expand All @@ -1280,20 +1291,14 @@ SCIP_RETCODE SDPAreadBlocks(
SCIP_CALL( readNextLine(scip, file, &data->buffer, &data->bufferlen, linecount, &success) );
}

/* reset LP block offset */
blockidxoffset = 0;

for (b = 0; b < data->nsdpblocks; b++)
for (file_b = 1; file_b <= data->nconsblocks; file_b++)
{
if ( nentriessdp[b] == 0 )
b = data->newblockidx[file_b - 1];
if ( b >= 0 && nentriessdp[b] == 0 )
{
emptysdpblocks++;

/* account for a possible LP block */
if ( data->idxlinconsblock >= 0 && b >= data->idxlinconsblock )
blockidxoffset = 1;

SCIPerrorMessage("SDP block number %d does not contain any nonzero entries!\n", b + 1 + blockidxoffset);
SCIPerrorMessage("SDP block number %d does not contain any nonzero entries!\n", file_b);
}
}

Expand Down Expand Up @@ -1582,7 +1587,7 @@ SCIP_RETCODE SDPAreadRank1(
)
{ /*lint --e{818}*/
SCIP_Bool success;
int blockidxoffset = 0;
int file_v;
int v;

assert( scip != NULL );
Expand Down Expand Up @@ -1627,29 +1632,28 @@ SCIP_RETCODE SDPAreadRank1(
}

/* switch from SDPA counting (starting from 1) to SCIP counting (starting from 0) */
file_v = v;
--v;

/* reset LP block offset */
blockidxoffset = 0;

if ( v == data->idxlinconsblock )
if ( data->newblockidx[v] < 0 )
{
SCIPerrorMessage("Given rank1 in line %" SCIP_LONGINT_FORMAT " for the LP block which is not valid.\n",
*linecount);
goto TERMINATE;
}

/* check if the LP block was already read and adjust the counter as well as the offset for error messages */
if ( data->idxlinconsblock >= 0 && v > data->idxlinconsblock )
if ( v >= data->nconsblocks )
{
v -= 1;
blockidxoffset = 1;
SCIPerrorMessage("Given rank1 in line %" SCIP_LONGINT_FORMAT " for block %d which does not exist!\n",
*linecount, file_v);
goto TERMINATE;
}

v = data->newblockidx[v];

if ( v < 0 || v >= data->nsdpblocks )
{
SCIPerrorMessage("Given rank1 in line %" SCIP_LONGINT_FORMAT " for SDP block %d which does not exist!\n",
*linecount, v + 1 + blockidxoffset);
*linecount, file_v);
goto TERMINATE;
}

Expand Down Expand Up @@ -1711,7 +1715,8 @@ SCIP_DECL_READERREAD(readerReadSdpa)
data->nlinconss = 0;
data->nvars = -1;
data->nconsblocks = -1;
data->idxlinconsblock = -1;
data->blockoffsets = NULL;
data->newblockidx = NULL;
data->bufferlen = 0;
data->sdpblockrank1 = NULL;
data->createdvars = NULL;
Expand Down
6 changes: 6 additions & 0 deletions unittests/src/readwrite.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,3 +362,9 @@ Test(readwrite, sign)

cr_assert_float_eq(obj1, obj2, EPS, "Optimal values differ: %g (SDPA from CBF with L-) != %g (SDPA from CBF with L+)\n", obj1, obj2);
}

/** Test 20 */
Test(readwrite, test20)
{
SCIP_CALL_STOP( runTests("../instances", "example_small_multiLP", "dat-s", 1, EPS, 1, TRUE) );
}