overhauled physics engine
This commit is contained in:
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
This is a short list for SDPA-M command.
|
||||
|
||||
(1) read_data.m
|
||||
>> [mDIM,nBLOCK,bLOCKsTRUCT,c,F] = read_data('example1.dat-s');
|
||||
will read 'example1.dat-s' into the SDPA-M structures.
|
||||
|
||||
(2) paramC.m
|
||||
>> OPTION=paramC;
|
||||
will prepare default parameter. You can change the parameter
|
||||
by this OPTION structure.
|
||||
|
||||
(3) sdpam.m
|
||||
>> [objVal,x,X,Y,INFO] = sdpam(mDIM,nBLOCK,bLOCKsTRUCT,c,F);
|
||||
or
|
||||
>> [objVal,x,X,Y,INFO] = sdpam(mDIM,nBLOCK,bLOCKsTRUCT,c,F,OPTION);
|
||||
will solve the SDP.
|
||||
|
||||
(4) gensdpafile.m
|
||||
>> gensdpafile('myexample.dat-s',mDIM,nBLOCK,bLOCKsTRUCT,c,F);
|
||||
will output the SDPA-M structure into 'myexample.dat-s'.
|
||||
|
||||
(5) initial_point.m
|
||||
>> [x0,X0,Y0] = initial_point('example1.ini-s', mDIM, nBLOCK, bLOCKsTRUCT);
|
||||
will read an initial point from 'example1.ini-s'.
|
||||
You need to prepare mDIM, nBLOCK, bLOCKsTRUCT by read_data.m
|
||||
|
||||
(6) SDPAToSedumi.m
|
||||
>> [At,b,c,K,blockStruct] = SDPAToSedumi('example1.dat-s');
|
||||
will read 'example1.dat-s' into SeDuMi structures with
|
||||
an additional structure 'blockStruct'.
|
||||
|
||||
(7) sedumiwrap.m
|
||||
>> [x,y,info]=sedumiwrap(A,b,c,K,pars,OPTION);
|
||||
will solve the SDP given in SeDuMi strucutres.
|
||||
The 5th argument 'pars' will be ignored
|
||||
and the 6th argument can be prepared by param.m
|
||||
|
||||
(8) SedumiToSDPA.m
|
||||
>> SedumiToSDPA('myexample.dat-s',A,b,c,K,'%8.16e');
|
||||
will output SeDuMi structures into 'myexample.dat-s'.
|
||||
'%8.16' determines the output style by printf-format.
|
||||
|
||||
(9) read_output.m
|
||||
>> [objVal,x,X,Y,INFO] = read_output('example1.result',mDIM,nBLOCK,bLOCKsTRUCT);
|
||||
will read the result file generated by SDPA.
|
||||
If you solve 'example1.dat-s' by
|
||||
$ ./sdpa example1.dat-s example1.result
|
||||
then this result can be read by
|
||||
>> [mDIM,nBLOCK,bLOCKsTRUCT,c,F] = read_data('example1.dat-s');
|
||||
>> [objVal,x,X,Y,INFO] = read_output('example1.result',mDIM,nBLOCK,bLOCKsTRUCT);
|
||||
|
||||
(10) read_outputSedumi.m
|
||||
>> [x,y,info] = read_outputSedumi('example1.result',m,K);
|
||||
will read the result file generated by SDPA.
|
||||
If you solve 'example1.dat-s' by
|
||||
$ ./sdpa example1.dat-s example1.result
|
||||
then this result can be read by
|
||||
>> [At,b,c,K,blockStruct] = SDPAToSedumi('example1.dat-s');
|
||||
>> [x,y,info] = read_outputSedumi('example1.result',m,K);
|
||||
|
||||
Vendored
+131
@@ -0,0 +1,131 @@
|
||||
#
|
||||
# SDPA-M: $Revision: 7.3 $
|
||||
#
|
||||
# For Matlab
|
||||
# $ make
|
||||
# For Octave
|
||||
# $ make COMPILE_ENVIRONMENT=octave
|
||||
|
||||
# after "make install", you can find
|
||||
# 'make.inc' in 'share/sdpa' sub-directory under the installed directory
|
||||
# For example
|
||||
# make MAKE_INCLUDE_DIR=/usr/share/sdpa
|
||||
# or
|
||||
# make MAKE_INCLUDE_DIR=/usr/local/share/sdpa
|
||||
# In addition, for Octave, you should try
|
||||
# make MAKE_INCLUDE_DIR=/usr/local/share/sdpa COMPILE_ENVIRONMENT=octave
|
||||
|
||||
|
||||
# To compile with mingw, the following command is a sample.
|
||||
# Your need to modify directory names and compiler names.
|
||||
# make MEX="i586-mingw32msvc-g++ -shared" COMPILE_ENVIRONMENT=octave \
|
||||
# PRINTF_INT_STYLE=-DPRINTF_INT_STYLE=\\\"%zd\\\" \
|
||||
# OUTPUT_FORMAT="-o \$@.mexw32" \
|
||||
# MATLAB_INCLUDE="-Imatlab-extern/include" \
|
||||
# MATLAB_LIBS="-I/matlab-extern/microsoft/libmx.lib -I/matlab-extern/microsoft/libmex.lib" \
|
||||
|
||||
|
||||
# for only SDPA-Project members
|
||||
# set DEVELOPEMENT_STAGE=1 to compile without 'make install'
|
||||
# For example
|
||||
# make MAKE_INCLUDE_DIR=../etc DEVELOPEMENT_STAGE=1
|
||||
# In addition, for Octave, you should try
|
||||
# make MAKE_INCLUDE_DIR=../etc DEVELOPEMENT_STAGE=1 COMPILE_ENVIRONMENT=octave
|
||||
|
||||
# This file is a component of SDPA
|
||||
# Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
MAKE_INCLUDE_DIR=..
|
||||
-include ${MAKE_INCLUDE_DIR}/make.inc
|
||||
# after "make install", you can find
|
||||
# 'make.inc' in 'share/sdpa' sub-directory under the installed directory
|
||||
# For example
|
||||
# make MAKE_INCLUDE_DIR=/usr/share/sdpa
|
||||
# or
|
||||
# make MAKE_INCLUDE_DIR=/usr/local/share/sdpa
|
||||
|
||||
MEX = mex
|
||||
DEF_FPIC = -fPIC
|
||||
|
||||
CXXFLAGSOPTIONS = CXXFLAGS="-Wall -fPIC" -O -DNDEBUG CC=${CC} CXX=${CXX}
|
||||
LARGEARRAYOPTION = -largeArrayDims
|
||||
|
||||
SDPA_INCLUDE = -I${SDPA_DIR}/include
|
||||
ifeq ($(DEVELOPEMENT_STAGE),1)
|
||||
SDPA_INCLUDE = -I..
|
||||
SDPA_LIB = ../libsdpa-c.a
|
||||
endif
|
||||
|
||||
PRINTF_INT_STYLE = -DPRINTF_INT_STYLE=\\\"%zd\\\"
|
||||
# Output format is usually automatically set by mex command.
|
||||
OUTPUT_FORMAT =
|
||||
|
||||
ifeq ($(COMPILE_ENVIRONMENT),octave)
|
||||
MEX = CC=${CC} CXX=${CXX} mkoctfile --mex
|
||||
CXXFLAGSOPTIONS =
|
||||
LARGEARRAYOPTION =
|
||||
PRINTF_INT_STYLE = -DPRINTF_INT_STYLE=\\\"%d\\\"
|
||||
endif
|
||||
|
||||
ALL_OPTION = ${CXXFLAGSOPTIONS} ${LARGEARRAYOPTION} ${PRINTF_INT_STYLE}
|
||||
|
||||
all: mexsdpaC mexSedumiWrapC
|
||||
# all: mexSedumiWrap
|
||||
|
||||
mexBinaryCheck:
|
||||
@echo "---------------------------------------------"
|
||||
@echo "Mex Compilation Start "
|
||||
@echo "---------------------------------------------"
|
||||
@if [ -f $(MEX) ]; then \
|
||||
echo "---------------------------------------------" ;\
|
||||
echo " We use " ;\
|
||||
echo " " $(MEX) ;\
|
||||
echo " for Mex compilaton " ;\
|
||||
echo "---------------------------------------------" ;\
|
||||
else \
|
||||
echo "---------------------------------------------" ;\
|
||||
echo "Automatic search is failed, " ;\
|
||||
echo " Set the full path for mex command mannually " ;\
|
||||
echo " in "`pwd`"/Makekefile" ;\
|
||||
echo " and try 'make' in `pwd` " ;\
|
||||
echo "---------------------------------------------" ;\
|
||||
false ;\
|
||||
fi
|
||||
|
||||
mexsdpaC:
|
||||
${MEX} ${ALL_OPTION} \
|
||||
${OUTPUT_FORMAT} \
|
||||
${SDPA_INCLUDE} ${sdpac_all_include} \
|
||||
mexsdpaC.cpp mexFprintf.c \
|
||||
${SDPA_LIB} ${sdpac_all_lib}
|
||||
|
||||
mexSedumiWrapC:
|
||||
${MEX} ${ALL_OPTION} \
|
||||
${OUTPUT_FORMAT} \
|
||||
${SDPA_INCLUDE} ${sdpac_all_include} \
|
||||
mexSedumiWrapC.cpp mexFprintf.c \
|
||||
${SDPA_LIB} ${sdpac_all_lib}
|
||||
|
||||
# clean all generated files
|
||||
clean:
|
||||
rm -f *~ *.o
|
||||
dist-clean: clean
|
||||
rm -f mexsdpaC.mex* mexSedumiWrapC.mex*
|
||||
|
||||
#
|
||||
# End of File
|
||||
#
|
||||
Vendored
+116
@@ -0,0 +1,116 @@
|
||||
/* -------------------------------------------------------------
|
||||
|
||||
This file is a component of SDPA
|
||||
Copyright (C) 2004-2013 SDPA Project
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <mex.h>
|
||||
|
||||
|
||||
#define BUF_LENGTH 4096
|
||||
|
||||
int fprintf(FILE *stream, const char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg,format);
|
||||
int return_size = 0;
|
||||
if (stream == stdout) {
|
||||
char tmp_buf[BUF_LENGTH];
|
||||
vsprintf(tmp_buf,format,arg);
|
||||
#if 0
|
||||
printf("tmp_buf = %s",tmp_buf);
|
||||
#endif
|
||||
mexPrintf(tmp_buf);
|
||||
mexEvalString("drawnow;"); /* to dump string.*/
|
||||
return_size = strlen(tmp_buf);
|
||||
if ( return_size >= BUF_LENGTH ) {
|
||||
mexPrintf("Too Long Message To PrintOut "
|
||||
"(some part might be truncated)");
|
||||
}
|
||||
}
|
||||
else {
|
||||
return_size = vfprintf(stream,format,arg);
|
||||
}
|
||||
va_end(arg);
|
||||
return return_size;
|
||||
}
|
||||
|
||||
static int internal_fprintf(FILE *stream, const char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg,format);
|
||||
int return_size = 0;
|
||||
return_size = vfprintf(stream,format,arg);
|
||||
va_end(arg);
|
||||
return return_size;
|
||||
}
|
||||
|
||||
size_t fwrite(const void *ptr, size_t size, size_t nmemb,
|
||||
FILE *stream)
|
||||
{
|
||||
#if 1
|
||||
fprintf(stream,"%s",(const char*)ptr);
|
||||
#else
|
||||
// internal_fprintf does not work well here
|
||||
internal_fprintf(stream, (const char*) internal_fprintf);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fputc(int c, FILE* fp)
|
||||
{
|
||||
if (fp == stdout) {
|
||||
mexPrintf("%c",(unsigned char)c);
|
||||
}
|
||||
else {
|
||||
internal_fprintf(fp,"%c",c);
|
||||
/* fprintf(fp,"%c ",c);*/
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
/*Only GNU, to avoid
|
||||
warning: 'noreturn' function does return
|
||||
*/
|
||||
static void internal_exit() __attribute__ ((noreturn));
|
||||
extern void mexErrMsgTxt(const char*) __attribute__ ((noreturn));
|
||||
void exit() __attribute__ ((noreturn));
|
||||
void abort() __attribute__ ((noreturn));
|
||||
#endif
|
||||
|
||||
static void internal_exit()
|
||||
{
|
||||
mexWarnMsgTxt("SDPA-C exits with some error.");
|
||||
mexWarnMsgTxt("Matlab should be reboot to clear up memory space.");
|
||||
mexErrMsgTxt("SDPA-C exits with some error.");
|
||||
}
|
||||
|
||||
void exit(int status)
|
||||
{
|
||||
internal_exit();
|
||||
}
|
||||
void abort(void)
|
||||
{
|
||||
internal_exit();
|
||||
}
|
||||
Vendored
+655
@@ -0,0 +1,655 @@
|
||||
/*
|
||||
* This file is a component of SDPA
|
||||
* Copyright (C) 2004-2013 SDPA Project
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* SDPA-M: 7.3
|
||||
* mexsdpa.cpp
|
||||
*/
|
||||
|
||||
#include <mex.h>
|
||||
/*
|
||||
* SDPA header files
|
||||
*/
|
||||
#include <sdpa_tool.h>
|
||||
#include <sdpa_call.h>
|
||||
using namespace sdpa;
|
||||
|
||||
extern void _main();
|
||||
|
||||
void sdpasolver(mxArray* At_ptr, mxArray* b_ptr, mxArray* c_ptr,
|
||||
mxArray* K_ptr, mxArray* OPTION_ptr,
|
||||
mxArray* x_ptr, mxArray* y_ptr,
|
||||
mxArray* info_ptr)
|
||||
{
|
||||
time_t ltime;
|
||||
time(<ime);
|
||||
char string_time[1024];
|
||||
strcpy(string_time,ctime(<ime));
|
||||
string_time[strlen(string_time)-1]='\0';
|
||||
|
||||
SDPA sdpa;
|
||||
|
||||
int maxIteration = 0;
|
||||
double param = 0.0;
|
||||
/* mxArray pointer */
|
||||
mxArray *field_ptr = NULL;
|
||||
int nSymmChk = 0;
|
||||
int nDimacs = 0;
|
||||
|
||||
/* strings for phase value */
|
||||
const char *szPhase[] = {
|
||||
"noINFO", "pFEAS", "dFEAS", "pdFEAS", "pdINF",
|
||||
"pFEAS_dINF", "pINF_dFEAS", "pdOPT", "pUNBD", "dUNBD"};
|
||||
|
||||
/* output file */
|
||||
char *outfile = NULL;
|
||||
FILE *fp = NULL;
|
||||
FILE *fpResult = NULL;
|
||||
int nOutfile = 0;
|
||||
|
||||
mwSize mDIM;
|
||||
mwSize nBLOCK;
|
||||
|
||||
/* temporary variables */
|
||||
mwIndex k;
|
||||
int size;
|
||||
mwSize mwsize;
|
||||
double *tmp_ptr = NULL;
|
||||
char* tmpPrint = NULL;
|
||||
|
||||
TimeStart(SDPA_START);
|
||||
TimeStart(SDPA_CONVERT_START);
|
||||
|
||||
/*** Set SDPA parameters by OPTIONS ***/
|
||||
/* Max Iteration */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "maxIteration");
|
||||
if( field_ptr != NULL ){
|
||||
maxIteration = (int)mxGetScalar(field_ptr);
|
||||
// mexPrintf("maxIteration = %d\n",maxIteration);
|
||||
sdpa.setParameterMaxIteration(maxIteration);
|
||||
}
|
||||
/* epsilonStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "epsilonStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterEpsilonStar(param);
|
||||
}
|
||||
/* lambdaStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "lambdaStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterLambdaStar(param);
|
||||
}
|
||||
/* omegaStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "omegaStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterOmegaStar(param);
|
||||
}
|
||||
/* lowerBound */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "lowerBound");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterLowerBound(param);
|
||||
}
|
||||
/* upperBound */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "upperBound");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterUpperBound(param);
|
||||
}
|
||||
/* betaStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "betaStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterBetaStar(param);
|
||||
}
|
||||
/* betaBar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "betaBar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterBetaBar(param);
|
||||
}
|
||||
/* gammaStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "gammaStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterGammaStar(param);
|
||||
}
|
||||
/* epsilonDash */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "epsilonDash");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterEpsilonDash(param);
|
||||
}
|
||||
/* xPrint */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "xPrint");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
sdpa.setParameterPrintXVec(tmpPrint);
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
/* XPrint */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "XPrint");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
sdpa.setParameterPrintXMat(tmpPrint);
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
/* YPrint */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "YPrint");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
sdpa.setParameterPrintYMat(tmpPrint);
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
/* infPrint */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "infPrint");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
sdpa.setParameterPrintInformation(tmpPrint);
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
|
||||
|
||||
/* isSymmetric */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "isSymmetric");
|
||||
if( field_ptr != NULL ){
|
||||
nSymmChk = (int)mxGetScalar(field_ptr);
|
||||
}
|
||||
/* isDimacs */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "isDimacs");
|
||||
if( field_ptr != NULL ){
|
||||
nDimacs = (int)mxGetScalar(field_ptr);
|
||||
}
|
||||
/* print */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "print");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
if (mwsize == 1) {
|
||||
// mexPrintf("display is NULL\n");
|
||||
fp = NULL;
|
||||
}
|
||||
else {
|
||||
outfile = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, outfile, mwsize);
|
||||
if( strncmp("display", outfile, mwsize - 1) == 0 ){
|
||||
fp = stdout;
|
||||
} else if( strncmp("no", outfile, mwsize - 1) == 0 ){
|
||||
fp = NULL;
|
||||
} else {
|
||||
fp = fopen(outfile, "at");
|
||||
if( fp == NULL ){
|
||||
mexPrintf("Failed to open %s\n", outfile);
|
||||
fp = stdout;
|
||||
} else {
|
||||
nOutfile = 1;
|
||||
}
|
||||
}
|
||||
mxFree(outfile);
|
||||
}
|
||||
} else {
|
||||
/* default setting is displaying information to stdout */
|
||||
fp = stdout;
|
||||
}
|
||||
sdpa.setDisplay(fp);
|
||||
|
||||
/* resultFile */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "resultFile");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
if (mwsize == 1) {
|
||||
// mexPrintf("resultFile is NULL\n");
|
||||
}
|
||||
else {
|
||||
outfile = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, outfile, mwsize);
|
||||
if ( strncmp("no", outfile, mwsize - 1) == 0 ) {
|
||||
mexPrintf("resultFile is NULL\n");
|
||||
}
|
||||
else {
|
||||
fpResult = fopen(outfile, "w");
|
||||
if ( fpResult == NULL ) {
|
||||
mexPrintf("Failed to open %s\n", outfile);
|
||||
mexPrintf("Skip the detail file\n");
|
||||
} else {
|
||||
sdpa.setResultFile(fpResult);
|
||||
}
|
||||
}
|
||||
mxFree(outfile);
|
||||
}
|
||||
}
|
||||
|
||||
if (fp) {
|
||||
fprintf(fp,"SDPA-C start at [%s]\n",string_time);
|
||||
}
|
||||
if (fpResult) {
|
||||
fprintf(fpResult,"SDPA-C start at [%s]\n",string_time);
|
||||
}
|
||||
|
||||
if (nDimacs != 0) {
|
||||
if (sdpa.judgeDimacsAvailability() == false) {
|
||||
if (fp) {
|
||||
fprintf(fp, "Dimacs will be skipped by XPrint and YPrint parameter.\n");
|
||||
}
|
||||
if (fpResult) {
|
||||
fprintf(fpResult, "Dimacs will be skipped by XPrint and YPrint parameter.\n");
|
||||
}
|
||||
nDimacs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* NumThreads */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "NumThreads");
|
||||
if( field_ptr != NULL ){
|
||||
sdpa.setNumThreads((int)mxGetScalar(field_ptr));
|
||||
}
|
||||
|
||||
/*** initialize SDPA class members ***/
|
||||
/* mDIM */
|
||||
mDIM = mxGetN(At_ptr);
|
||||
sdpa.inputConstraintNumber(mDIM);
|
||||
/* nBLOCK */
|
||||
nBLOCK = 0;
|
||||
mwSize K_l = 0;
|
||||
int isK_l = 0; // 1 (K_l > 0) or 0 (K_l == 0)
|
||||
field_ptr = mxGetField(K_ptr, 0, "l");
|
||||
if (field_ptr != NULL) {
|
||||
K_l = (mwSize)((mxGetPr(field_ptr))[0]);
|
||||
#if 0
|
||||
mexPrintf("K_l = %zd\n", K_l);
|
||||
#endif
|
||||
if (K_l > 0) {
|
||||
isK_l = 1;
|
||||
nBLOCK++;
|
||||
}
|
||||
}
|
||||
mwSize* K_s = NULL;
|
||||
mwSize* K_sdpConeStart = NULL;
|
||||
int K_sdpNoCones = 0;
|
||||
field_ptr = mxGetField(K_ptr, 0, "s");
|
||||
if (field_ptr != NULL) {
|
||||
K_sdpNoCones = (int) mxGetM(field_ptr);
|
||||
K_s = (mwSize*) mxCalloc(K_sdpNoCones, sizeof(mwSize));
|
||||
K_sdpConeStart = (mwSize*) mxCalloc(K_sdpNoCones+1, sizeof(mwSize));
|
||||
K_sdpConeStart[0] = 0;
|
||||
for (int l=0; l<K_sdpNoCones; ++l) {
|
||||
K_s[l] = (mwSize)((mxGetPr(field_ptr))[l]);
|
||||
#if 0
|
||||
mexPrintf("K_s[%zd] = %zd\n", l+isK_l+1, K_s[l]);
|
||||
#endif
|
||||
K_sdpConeStart[l+1] = K_sdpConeStart[l] + K_s[l]*K_s[l];
|
||||
nBLOCK++;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
mexPrintf("isK_l = %d, nBlock = %d \n", isK_l, nBLOCK);
|
||||
#endif
|
||||
sdpa.inputBlockNumber(nBLOCK);
|
||||
if (isK_l > 0) {
|
||||
sdpa.inputBlockSize(1, K_l);
|
||||
sdpa.inputBlockType(1, SDPA::LP);
|
||||
}
|
||||
for (int l=0; l<K_sdpNoCones; ++l) {
|
||||
#if 0
|
||||
mexPrintf("l+isK_l+1 = %d, K_s = %d \n", l+isK_l+1, K_s[l]);
|
||||
#endif
|
||||
sdpa.inputBlockSize(l+isK_l+1, K_s[l]);
|
||||
sdpa.inputBlockType(l+isK_l+1, SDPA::SDP);
|
||||
}
|
||||
|
||||
/* Execute initializeUpperTriangleSpace() */
|
||||
sdpa.initializeUpperTriangleSpace();
|
||||
|
||||
/* cVECT = -b*/
|
||||
double* b = mxGetPr(b_ptr);
|
||||
for(mwSize i = 0; i < mDIM; i++){
|
||||
sdpa.inputCVec((int)i+1, -b[i]);
|
||||
}
|
||||
|
||||
/*** Count NonZeroNumber in coefficience matrices ***/
|
||||
// Do nothing for SDPA 7
|
||||
|
||||
/* F_0 = - C */
|
||||
if (mxIsEmpty(c_ptr) || mxGetNzmax(c_ptr) == 0
|
||||
|| (mxGetJc(c_ptr))[1] == 0) {
|
||||
mexPrintf("c = empty\n");
|
||||
}
|
||||
else {
|
||||
mwIndex* C_row = mxGetIr(c_ptr);
|
||||
mwIndex* C_column = mxGetJc(c_ptr);
|
||||
double* C_ele = mxGetPr(c_ptr);
|
||||
mwIndex C_length = C_column[1];
|
||||
int currentSdpCone = 0;
|
||||
for (mwSize index = 0; index<C_length; ++index) {
|
||||
mwSize C_j = C_row[index];
|
||||
/* A_0 = - C */
|
||||
double ele = -C_ele[index];
|
||||
// mexPrintf("C_j = %zd, ele = %e\n", C_j, ele);
|
||||
if (C_j < K_l) {
|
||||
sdpa.inputElement(0, 1, C_j+1, C_j+1, ele);
|
||||
}
|
||||
else {
|
||||
C_j -= K_l;
|
||||
while (K_sdpConeStart[currentSdpCone+1] <= C_j) {
|
||||
currentSdpCone++;
|
||||
}
|
||||
int index2, i,j;
|
||||
index2 = C_j - K_sdpConeStart[currentSdpCone];
|
||||
i = index2 / K_s[currentSdpCone];
|
||||
j = index2 % K_s[currentSdpCone];
|
||||
if (i <= j) {
|
||||
// Only upper triangular is input
|
||||
#if 0
|
||||
mexPrintf("input k=%d, l=%d, i=%d, j=%d, v=%e\n",
|
||||
0, isK_l + currentSdpCone+1,i+1, j+1, ele);
|
||||
#endif
|
||||
sdpa.inputElement(0, isK_l + currentSdpCone+1,i+1, j+1, ele);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* F_{k+1} = - A_k */
|
||||
mwIndex* At_row = mxGetIr(At_ptr);
|
||||
mwIndex* At_column = mxGetJc(At_ptr);
|
||||
double* At_ele = mxGetPr(At_ptr);
|
||||
for (k=0; k<mDIM; ++k) {
|
||||
mwIndex Ak_start = At_column[k ];
|
||||
mwIndex Ak_end = At_column[k+1];
|
||||
int currentSdpCone = 0;
|
||||
for (mwSize index = Ak_start; index<Ak_end; ++index) {
|
||||
mwSize Ak_j = At_row[index];
|
||||
/* F_{k+1} = - A_k */
|
||||
double ele = -At_ele[index];
|
||||
if (Ak_j < K_l) {
|
||||
sdpa.inputElement(k+1, 1, Ak_j+1, Ak_j+1, ele);
|
||||
}
|
||||
else {
|
||||
Ak_j -= K_l;
|
||||
while (K_sdpConeStart[currentSdpCone+1] <= Ak_j) {
|
||||
currentSdpCone++;
|
||||
}
|
||||
int index2, i,j;
|
||||
index2 = Ak_j - K_sdpConeStart[currentSdpCone];
|
||||
i = index2 / K_s[currentSdpCone];
|
||||
j = index2 % K_s[currentSdpCone];
|
||||
if (i <= j) {
|
||||
// Only upper triangular is input
|
||||
#if 0
|
||||
mexPrintf("input k=%d, l=%d, i=%d, j=%d, v=%e\n",
|
||||
k+1, isK_l + currentSdpCone+1,i+1, j+1, ele);
|
||||
#endif
|
||||
sdpa.inputElement(k+1, isK_l + currentSdpCone+1,i+1, j+1, ele);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*** Check the consistence of F, c ***/
|
||||
if( nSymmChk ){
|
||||
sdpa.initializeUpperTriangle(true);
|
||||
}
|
||||
else {
|
||||
sdpa.initializeUpperTriangle(false);
|
||||
}
|
||||
|
||||
// sdpa.writeInputSparse((char*)"b.dat-s",(char*)"%e");
|
||||
|
||||
/*** Solve SDP ***/
|
||||
sdpa.initializeSolve();
|
||||
mexPrintf("Converted to SDPA internal data / ");
|
||||
mexPrintf("Starting SDPA-C main loop\n");
|
||||
TimeEnd(SDPA_CONVERT_END);
|
||||
TimeStart(SDPA_SOLVE_START);
|
||||
sdpa.solve();
|
||||
TimeEnd(SDPA_SOLVE_END);
|
||||
TimeStart(SDPA_RETRIEVE_START);
|
||||
mexPrintf("Converting optimal solution to Sedumi format\n");
|
||||
/**** Set output values to arguments ****/
|
||||
|
||||
/* Optimal value for xVec */
|
||||
double* y = mxGetPr(y_ptr);
|
||||
tmp_ptr = sdpa.getResultXVec();
|
||||
if( tmp_ptr != NULL ){
|
||||
for(k = 0; k < mDIM; k++){
|
||||
y[k] = tmp_ptr[k];
|
||||
}
|
||||
}
|
||||
|
||||
/* Optimal value for YMat */
|
||||
double* x = mxGetPr(x_ptr);
|
||||
// if sdpa.getResultYMat(1) == NULL, YMat is not computed
|
||||
if (sdpa.getResultYMat(1) != NULL) {
|
||||
if (isK_l > 0) {
|
||||
size = sdpa.getBlockSize(1);
|
||||
tmp_ptr = sdpa.getResultYMat(1);
|
||||
for (int index = 0; index < size; ++index) {
|
||||
x[index] = tmp_ptr[index];
|
||||
}
|
||||
}
|
||||
for (int l=0; l<K_sdpNoCones; ++l) {
|
||||
size = sdpa.getBlockSize(l+isK_l+1);
|
||||
tmp_ptr = sdpa.getResultYMat(l+isK_l+1);
|
||||
for (int index = 0; index < size*size; ++index) {
|
||||
x[K_l + K_sdpConeStart[l] + index] = tmp_ptr[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
rMessage("x is not computed by YPrint, and x will be empty matrix.");
|
||||
}
|
||||
TimeEnd(SDPA_RETRIEVE_END);
|
||||
|
||||
/* Dimacs Error Information */
|
||||
if (nDimacs != 0) {
|
||||
field_ptr = mxCreateNumericMatrix(6,1,mxDOUBLE_CLASS,mxREAL);
|
||||
double* dimacs_store = mxGetPr(field_ptr);
|
||||
double dimacs_error[7];
|
||||
if (sdpa.judgeDimacsAvailability() == false) {
|
||||
for (int i=0; i<=6; i++) {
|
||||
dimacs_store[i] = 0.0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mexPrintf("Computing Dimacs Error\n");
|
||||
sdpa.getDimacsError(dimacs_error);
|
||||
for (int i=1; i<=6; i++) {
|
||||
dimacs_store[i-1] = dimacs_error[i];
|
||||
}
|
||||
}
|
||||
mxSetField(info_ptr, 0, "dimacs", field_ptr);
|
||||
}
|
||||
|
||||
|
||||
/* Phase information */
|
||||
field_ptr = mxCreateString(szPhase[sdpa.getPhaseValue()]);
|
||||
mxSetField(info_ptr, 0, "phasevalue", field_ptr);
|
||||
/* Iteration */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = (double)sdpa.getIteration();
|
||||
mxSetField(info_ptr, 0, "iteration", field_ptr);
|
||||
|
||||
/* primalObj */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = -sdpa.getDualObj();
|
||||
mxSetField(info_ptr, 0, "primalObj", field_ptr);
|
||||
/* dualObj */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = -sdpa.getPrimalObj();
|
||||
mxSetField(info_ptr, 0, "dualObj", field_ptr);
|
||||
/* primalError */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = sdpa.getDualError();
|
||||
mxSetField(info_ptr, 0, "primalError", field_ptr);
|
||||
/* dualError */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = sdpa.getPrimalError();
|
||||
mxSetField(info_ptr, 0, "dualError", field_ptr);
|
||||
/* digits */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = sdpa.getDigits();
|
||||
mxSetField(info_ptr, 0, "digits", field_ptr);
|
||||
/* dualityGap */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = sdpa.getDualityGap();
|
||||
mxSetField(info_ptr, 0, "dualityGap", field_ptr);
|
||||
/* mu */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = sdpa.getMu();
|
||||
mxSetField(info_ptr, 0, "mu", field_ptr);
|
||||
|
||||
/* solveTime */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = TimeCal(SDPA_SOLVE_START,SDPA_SOLVE_END);
|
||||
mxSetField(info_ptr, 0, "solveTime", field_ptr);
|
||||
/* convertingTime */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = TimeCal(SDPA_CONVERT_START,SDPA_CONVERT_END);
|
||||
mxSetField(info_ptr, 0, "convertingTime", field_ptr);
|
||||
/* retrivingTime */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = TimeCal(SDPA_RETRIEVE_START,SDPA_RETRIEVE_END);
|
||||
mxSetField(info_ptr, 0, "retrievingTime", field_ptr);
|
||||
/* retrivingTime */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
TimeEnd(SDPA_END);
|
||||
*mxGetPr(field_ptr) = TimeCal(SDPA_START,SDPA_END);
|
||||
mxSetField(info_ptr, 0, "sdpaTime", field_ptr);
|
||||
|
||||
time(<ime);
|
||||
strcpy(string_time,ctime(<ime));
|
||||
string_time[strlen(string_time)-1]='\0';
|
||||
|
||||
if (fp) {
|
||||
fprintf(fp,"SDPA-C end at [%s]\n",string_time);
|
||||
}
|
||||
if (fpResult) {
|
||||
fprintf(fpResult,"SDPA-C end at [%s]\n",string_time);
|
||||
}
|
||||
/* close output file */
|
||||
if( nOutfile ){
|
||||
fclose(fp);
|
||||
}
|
||||
if (fpResult != NULL) {
|
||||
fclose(fpResult);
|
||||
}
|
||||
|
||||
/*** Free allocated memory ****/
|
||||
mxFree(K_s);
|
||||
mxFree(K_sdpConeStart);
|
||||
sdpa.finalize();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Matlab gateway function
|
||||
*/
|
||||
void mexFunction(int nlhs, mxArray *plhs[],
|
||||
int nrhs, const mxArray *prhs[])
|
||||
{
|
||||
/* Decleration of variables */
|
||||
|
||||
mxArray* At_ptr;
|
||||
mxArray* b_ptr;
|
||||
mxArray* c_ptr;
|
||||
mxArray* K_ptr;
|
||||
mxArray* OPTION_ptr;
|
||||
|
||||
mxArray* x_ptr;
|
||||
mxArray* y_ptr;
|
||||
mxArray* info_ptr;
|
||||
|
||||
const char *fnames[] = {
|
||||
"phasevalue",
|
||||
"iteration",
|
||||
"cpusec",
|
||||
"primalObj",
|
||||
"dualObj",
|
||||
"primalError",
|
||||
"dualError",
|
||||
"digits",
|
||||
"dualityGap",
|
||||
"mu",
|
||||
"dimacs",
|
||||
"solveTime",
|
||||
"convertingTime",
|
||||
"retrievingTime",
|
||||
"sdpaTime"
|
||||
};
|
||||
|
||||
/* Get the pointer of input variables */
|
||||
At_ptr = (mxArray*)prhs[0];
|
||||
b_ptr = (mxArray*)prhs[1];
|
||||
c_ptr = (mxArray*)prhs[2];
|
||||
K_ptr = (mxArray*)prhs[3];
|
||||
OPTION_ptr = (mxArray*)prhs[4];
|
||||
|
||||
mwSize m = mxGetM(b_ptr);
|
||||
mwSize n = mxGetM(c_ptr);
|
||||
|
||||
mxArray *field_ptr = NULL;
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "YPrint");
|
||||
bool x_ptr_empty = false;
|
||||
if( field_ptr != NULL ){
|
||||
mwSize mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
char* tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
#if 0
|
||||
rMessage("tmpPrint = " << tmpPrint
|
||||
<< " : NO_P_FORMAT " << NO_P_FORMAT);
|
||||
#endif
|
||||
if (strcmp(tmpPrint,NO_P_FORMAT) == 0) {
|
||||
x_ptr_empty = true;
|
||||
}
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
/* Create cellarrays for the output variables */
|
||||
if (x_ptr_empty == true) {
|
||||
rMessage("x is not computed by YPrint, and x will be empty matrix.");
|
||||
plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
|
||||
}
|
||||
else {
|
||||
plhs[0] = mxCreateDoubleMatrix(n,1,mxREAL);
|
||||
}
|
||||
plhs[1] = mxCreateDoubleMatrix(m,1,mxREAL);
|
||||
plhs[2] = mxCreateStructMatrix(1,1,15,fnames);
|
||||
|
||||
//Get the pointer of output variables
|
||||
x_ptr = plhs[0];
|
||||
y_ptr = plhs[1];
|
||||
info_ptr = plhs[2];
|
||||
|
||||
/* Call sdpasolver here */
|
||||
sdpasolver(At_ptr,b_ptr,c_ptr,K_ptr,OPTION_ptr,
|
||||
x_ptr,y_ptr,info_ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* End of File
|
||||
*/
|
||||
Vendored
+842
@@ -0,0 +1,842 @@
|
||||
/*
|
||||
* This file is a component of SDPA
|
||||
* Copyright (C) 2004-2013 SDPA Project
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* SDPA-M: 7.3
|
||||
* mexsdpa.cpp
|
||||
*/
|
||||
|
||||
#include <mex.h>
|
||||
/*
|
||||
* SDPA header files
|
||||
*/
|
||||
#include <sdpa_call.h>
|
||||
|
||||
extern void _main();
|
||||
|
||||
void sdpasolver(double *mDIM_ptr,
|
||||
double *nBLOCK_ptr,
|
||||
double *bLOCKsTRUCT_ptr,
|
||||
double *c_ptr,
|
||||
mxArray *F_ptr,
|
||||
double *x0_ptr,
|
||||
mxArray *X0_ptr,
|
||||
mxArray *Y0_ptr,
|
||||
mxArray *OPTION_ptr,
|
||||
int IniPt,
|
||||
double *objVal_ptr,
|
||||
double *x_ptr,
|
||||
mxArray *X_ptr,
|
||||
mxArray *Y_ptr,
|
||||
mxArray *INFO_ptr)
|
||||
{
|
||||
time_t ltime;
|
||||
time(<ime);
|
||||
char string_time[1024];
|
||||
strcpy(string_time,ctime(<ime));
|
||||
string_time[strlen(string_time)-1]='\0';
|
||||
|
||||
SDPA sdpa;
|
||||
|
||||
int maxIteration = 0;
|
||||
double param = 0.0;
|
||||
/* mxArray pointer */
|
||||
mxArray *field_ptr = NULL;
|
||||
mxArray *cell_ptr = NULL;
|
||||
|
||||
int nSymmChk = 0;
|
||||
int nDimacs = 0;
|
||||
|
||||
/* strings for phase value */
|
||||
const char *szPhase[] = {
|
||||
"noINFO", "pFEAS", "dFEAS", "pdFEAS", "pdINF",
|
||||
"pFEAS_dINF", "pINF_dFEAS", "pdOPT", "pUNBD", "dUNBD"};
|
||||
|
||||
/* output file */
|
||||
char *outfile = NULL;
|
||||
FILE *fp = NULL;
|
||||
FILE *fpResult = NULL;
|
||||
int nOutfile = 0;
|
||||
|
||||
mwSize mDIM;
|
||||
mwSize nBLOCK;
|
||||
|
||||
/* temporary variables */
|
||||
mwIndex i,j,k,l;
|
||||
int size;
|
||||
mwSize mwsize;
|
||||
mwIndex idx, startidx, endidx;
|
||||
mwSize sizeM, sizeN;
|
||||
mwIndex *subscript = NULL;
|
||||
mwIndex *dims = NULL;
|
||||
int cell_index = 0;
|
||||
mwIndex *ir_ptr = NULL;
|
||||
mwIndex *jc_ptr = NULL;
|
||||
double *tmp_ptr = NULL;
|
||||
double *result_ptr = NULL;
|
||||
char* tmpPrint = NULL;
|
||||
|
||||
/*** Set SDPA parameters by OPTIONS ***/
|
||||
/* Max Iteration */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "maxIteration");
|
||||
if( field_ptr != NULL ){
|
||||
maxIteration = (int)mxGetScalar(field_ptr);
|
||||
sdpa.setParameterMaxIteration(maxIteration);
|
||||
}
|
||||
/* epsilonStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "epsilonStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterEpsilonStar(param);
|
||||
}
|
||||
/* lambdaStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "lambdaStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterLambdaStar(param);
|
||||
}
|
||||
/* omegaStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "omegaStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterOmegaStar(param);
|
||||
}
|
||||
/* lowerBound */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "lowerBound");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterLowerBound(param);
|
||||
}
|
||||
/* upperBound */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "upperBound");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterUpperBound(param);
|
||||
}
|
||||
/* betaStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "betaStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterBetaStar(param);
|
||||
}
|
||||
/* betaBar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "betaBar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterBetaBar(param);
|
||||
}
|
||||
/* gammaStar */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "gammaStar");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterGammaStar(param);
|
||||
}
|
||||
/* epsilonDash */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "epsilonDash");
|
||||
if( field_ptr != NULL ){
|
||||
param = *mxGetPr(field_ptr);
|
||||
sdpa.setParameterEpsilonDash(param);
|
||||
}
|
||||
/* xPrint */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "xPrint");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
sdpa.setParameterPrintXVec(tmpPrint);
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
/* XPrint */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "XPrint");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
sdpa.setParameterPrintXMat(tmpPrint);
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
/* YPrint */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "YPrint");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
sdpa.setParameterPrintYMat(tmpPrint);
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
/* infPrint */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "infPrint");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
tmpPrint = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, tmpPrint, mwsize);
|
||||
sdpa.setParameterPrintInformation(tmpPrint);
|
||||
mxFree(tmpPrint);
|
||||
}
|
||||
|
||||
/* isSymmetric */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "isSymmetric");
|
||||
if( field_ptr != NULL ){
|
||||
nSymmChk = (int)mxGetScalar(field_ptr);
|
||||
}
|
||||
/* isDimacs */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "isDimacs");
|
||||
if( field_ptr != NULL ){
|
||||
nDimacs = (int)mxGetScalar(field_ptr);
|
||||
}
|
||||
/* print */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "print");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
if (mwsize == 1) {
|
||||
// mexPrintf("display is NULL\n");
|
||||
fp = NULL;
|
||||
}
|
||||
else {
|
||||
outfile = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, outfile, mwsize);
|
||||
if( strncmp("display", outfile, mwsize - 1) == 0 ){
|
||||
fp = stdout;
|
||||
} else if( strncmp("no", outfile, mwsize - 1) == 0 ){
|
||||
fp = NULL;
|
||||
} else {
|
||||
fp = fopen(outfile, "at");
|
||||
if( fp == NULL ){
|
||||
mexPrintf("Failed to open %s\n", outfile);
|
||||
fp = stdout;
|
||||
} else {
|
||||
nOutfile = 1;
|
||||
}
|
||||
}
|
||||
mxFree(outfile);
|
||||
}
|
||||
} else {
|
||||
/* default setting is displaying information to stdout */
|
||||
fp = stdout;
|
||||
}
|
||||
sdpa.setDisplay(fp);
|
||||
|
||||
/* resultFile */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "resultFile");
|
||||
if( field_ptr != NULL ){
|
||||
mwsize = mxGetM(field_ptr) * mxGetN(field_ptr) + 1;
|
||||
if (mwsize == 1) {
|
||||
// mexPrintf("resultFile is NULL\n");
|
||||
}
|
||||
else {
|
||||
outfile = (char*)mxCalloc(mwsize, sizeof(char));
|
||||
mxGetString(field_ptr, outfile, mwsize);
|
||||
fpResult = fopen(outfile, "w");
|
||||
if( fpResult == NULL ){
|
||||
mexPrintf("Failed to open %s\n", outfile);
|
||||
mexPrintf("Skip the detail file\n");
|
||||
} else {
|
||||
sdpa.setResultFile(fpResult);
|
||||
}
|
||||
mxFree(outfile);
|
||||
}
|
||||
}
|
||||
|
||||
if (fp) {
|
||||
fprintf(fp,"SDPA-C start at [%s]\n",string_time);
|
||||
}
|
||||
if (fpResult) {
|
||||
fprintf(fpResult,"SDPA-C start at [%s]\n",string_time);
|
||||
}
|
||||
|
||||
if (nDimacs) {
|
||||
if (sdpa.judgeDimacsAvailability() == false) {
|
||||
if (fp) {
|
||||
fprintf(fp, "Dimacs will be skipped by XPrint and YPrint parameter.\n");
|
||||
}
|
||||
if (fpResult) {
|
||||
fprintf(fpResult, "Dimacs will be skipped by XPrint and YPrint parameter.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* NumThreads */
|
||||
field_ptr = mxGetField(OPTION_ptr, 0, "NumThreads");
|
||||
if( field_ptr != NULL ){
|
||||
sdpa.setNumThreads((int)mxGetScalar(field_ptr));
|
||||
}
|
||||
|
||||
/*** initialize SDPA class members ***/
|
||||
/* mDIM */
|
||||
mDIM = (mwSize)(*mDIM_ptr);
|
||||
sdpa.inputConstraintNumber(mDIM);
|
||||
/* nBLOCK */
|
||||
nBLOCK = (mwSize)(*nBLOCK_ptr);
|
||||
sdpa.inputBlockNumber(nBLOCK);
|
||||
/* bLOCKsTRUCT */
|
||||
for(i = 0; i < nBLOCK; i++){
|
||||
int bs = (int)(bLOCKsTRUCT_ptr[i]);
|
||||
sdpa.inputBlockSize(i+1,bs);
|
||||
if (bs < 0 || bs == 1) {
|
||||
sdpa.inputBlockType(i+1,SDPA::LP);
|
||||
}
|
||||
else {
|
||||
sdpa.inputBlockType(i+1,SDPA::SDP);
|
||||
}
|
||||
}
|
||||
/* Execute initializeUpperTriangleSpace() */
|
||||
sdpa.initializeUpperTriangleSpace();
|
||||
/* cVECT */
|
||||
for(i = 0; i < mDIM; i++){
|
||||
sdpa.inputCVec(i+1, c_ptr[i]);
|
||||
}
|
||||
|
||||
/*** Count NonZeroNumber in coefficience matrices ***/
|
||||
// Do nothing for SDPA 7
|
||||
|
||||
/*** Set coefficience matrices value ***/
|
||||
subscript = (mwIndex*)mxCalloc(2,sizeof(mwIndex));
|
||||
dims = (mwIndex*)mxGetDimensions(F_ptr);
|
||||
for(l = 0; l < dims[0]; l++){
|
||||
for(k = 0; k < dims[1]; k++){
|
||||
subscript[0]=l; subscript[1]=k;
|
||||
cell_index = mxCalcSingleSubscript(F_ptr, 2, subscript);
|
||||
cell_ptr = mxGetCell(F_ptr, cell_index);
|
||||
// mxGetDimensions at the next line is redundant,
|
||||
// but this is necessary to octave
|
||||
dims = (mwIndex*)mxGetDimensions(F_ptr);
|
||||
if( cell_ptr == NULL || mxIsEmpty(cell_ptr) ){
|
||||
/* If the cell is empty, we assume this cell as zero matrix */
|
||||
continue;
|
||||
}
|
||||
sizeM = mxGetM(cell_ptr);
|
||||
sizeN = mxGetN(cell_ptr);
|
||||
tmp_ptr = mxGetPr(cell_ptr);
|
||||
if( mxIsSparse(cell_ptr) ){
|
||||
/* Sparse Matrix */
|
||||
ir_ptr = mxGetIr(cell_ptr);
|
||||
jc_ptr = mxGetJc(cell_ptr);
|
||||
if( sizeM == 1 && sizeN != 1 ){
|
||||
/* Row Vector Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
startidx = jc_ptr[j];
|
||||
endidx = jc_ptr[j+1];
|
||||
if( startidx == endidx ){ continue; }
|
||||
sdpa.inputElement( k, l+1, j+1, j+1, tmp_ptr[startidx]);
|
||||
}
|
||||
} else if( sizeM != 1 && sizeN == 1 ){
|
||||
/* Column Vector Case */
|
||||
endidx = jc_ptr[sizeN];
|
||||
for(idx = 0; idx < endidx; idx++){
|
||||
i = ir_ptr[idx];
|
||||
sdpa.inputElement( k, l+1, i+1, i+1, tmp_ptr[idx]);
|
||||
}
|
||||
} else {
|
||||
/* Matrix Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
startidx = jc_ptr[j];
|
||||
endidx = jc_ptr[j+1];
|
||||
if( startidx == endidx ){ continue; }
|
||||
for(idx = startidx; idx < endidx; idx++){
|
||||
i = ir_ptr[idx];
|
||||
if( i <= j ){
|
||||
sdpa.inputElement( k, l+1, i+1, j+1, tmp_ptr[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Dense Matrix */
|
||||
if( sdpa.getBlockType(l+1)==SDPA::SDP ){
|
||||
/* Full Matrix */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
for(i = 0; i < sizeM; i++){
|
||||
if( i <= j ){
|
||||
if( tmp_ptr[j * sizeN + i] != 0 ){
|
||||
sdpa.inputElement(k, l+1, i+1, j+1,
|
||||
tmp_ptr[j * sizeN + i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Diagonal Matrix */
|
||||
if( sizeM == 1 && sizeN != 1 ){
|
||||
/* Row Vector Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
if( tmp_ptr[j] != 0 ){
|
||||
sdpa.inputElement( k, l+1, j+1, j+1, tmp_ptr[j]);
|
||||
}
|
||||
}
|
||||
} else if( sizeM != 1 && sizeN == 1 ){
|
||||
/* Column Vector Case */
|
||||
for(i = 0; i < sizeM; i++){
|
||||
if( tmp_ptr[i] != 0 ){
|
||||
sdpa.inputElement( k, l+1, i+1, i+1, tmp_ptr[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Matrix Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
if( tmp_ptr[j * sizeN + j] != 0 ){
|
||||
sdpa.inputElement( k, l+1, j+1, j+1,
|
||||
tmp_ptr[j * sizeN + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*** Check the consistence of F, c ***/
|
||||
if( nSymmChk ){
|
||||
sdpa.initializeUpperTriangle(true);
|
||||
}
|
||||
else {
|
||||
sdpa.initializeUpperTriangle(false);
|
||||
}
|
||||
|
||||
/*** Check initial point ***/
|
||||
if( IniPt == 1 ){
|
||||
rMessage("Initial point is ignored in SDPA-C.");
|
||||
#if 0
|
||||
sdpa.setInitPoint(true);
|
||||
/* initial value for xVec */
|
||||
for(k = 0; k < mDIM; k++){
|
||||
sdpa.inputInitXVec( k+1, x0_ptr[k]);
|
||||
}
|
||||
/* initial value for XMat */
|
||||
cell_index = 0;
|
||||
for(l = 0; l < nBLOCK; l++){
|
||||
cell_ptr = mxGetCell(X0_ptr, cell_index);
|
||||
if( cell_ptr == NULL || mxIsEmpty(cell_ptr) ){
|
||||
/* If the cell is empty, we assume this cell as zero matrix */
|
||||
continue;
|
||||
}
|
||||
sizeM = mxGetM(cell_ptr);
|
||||
sizeN = mxGetN(cell_ptr);
|
||||
tmp_ptr = mxGetPr(cell_ptr);
|
||||
if( mxIsSparse(cell_ptr) ){
|
||||
/* Sparse Matrix */
|
||||
ir_ptr = mxGetIr(cell_ptr);
|
||||
jc_ptr = mxGetJc(cell_ptr);
|
||||
if( sizeM == 1 && sizeN != 1 ){
|
||||
/* Row Vector Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
startidx = jc_ptr[j];
|
||||
endidx = jc_ptr[j+1];
|
||||
if( startidx == endidx ){ continue; }
|
||||
sdpa.inputInitXMat(l+1, j+1, j+1, tmp_ptr[startidx]);
|
||||
}
|
||||
} else if( sizeM != 1 && sizeN == 1 ){
|
||||
/* Column Vector Case */
|
||||
endidx = jc_ptr[sizeN];
|
||||
for(idx = 0; idx < endidx; idx++){
|
||||
i = ir_ptr[idx];
|
||||
sdpa.inputInitXMat(l+1, i+1, i+1, tmp_ptr[idx]);
|
||||
}
|
||||
} else {
|
||||
/* Matrix Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
startidx = jc_ptr[j];
|
||||
endidx = jc_ptr[j+1];
|
||||
if( startidx == endidx ){ continue; }
|
||||
for(idx = startidx; idx < endidx; idx++){
|
||||
i = ir_ptr[idx];
|
||||
if( i <= j ){
|
||||
sdpa.inputInitXMat( l+1, i+1, j+1, tmp_ptr[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Dense Matrix */
|
||||
if( sdpa.getBlockType(l+1) == SDPA::SDP ){
|
||||
/* Full Matrix */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
for(i = 0; i < sizeM; i++){
|
||||
if( i <= j ){
|
||||
if( tmp_ptr[j * sizeN + i] != 0 ){
|
||||
sdpa.inputInitXMat( l+1, i+1, j+1,
|
||||
tmp_ptr[j * sizeN + i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Diagonal Matrix */
|
||||
if( sizeM == 1 && sizeN != 1 ){
|
||||
/* Row Vector Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
if( tmp_ptr[j] != 0 ){
|
||||
sdpa.inputInitXMat( l+1, j+1, j+1, tmp_ptr[j]);
|
||||
}
|
||||
}
|
||||
} else if( sizeM != 1 && sizeN == 1 ){
|
||||
/* Column Vector Case */
|
||||
for(i = 0; i < sizeM; i++){
|
||||
if( tmp_ptr[i] != 0 ){
|
||||
sdpa.inputInitXMat( l+1, i+1, i+1, tmp_ptr[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Matrix Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
if( tmp_ptr[j * sizeN + j] != 0 ){
|
||||
sdpa.inputInitXMat( l+1, j+1, j+1,
|
||||
tmp_ptr[j * sizeN + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cell_index++;
|
||||
}
|
||||
/* initial value for YMat */
|
||||
cell_index = 0;
|
||||
for(l = 0; l < nBLOCK; l++){
|
||||
cell_ptr = mxGetCell(Y0_ptr, cell_index);
|
||||
if( cell_ptr == NULL || mxIsEmpty(cell_ptr) ){
|
||||
/* If the cell is empty, we assume this cell as zero matrix */
|
||||
continue;
|
||||
}
|
||||
sizeM = mxGetM(cell_ptr);
|
||||
sizeN = mxGetN(cell_ptr);
|
||||
tmp_ptr = mxGetPr(cell_ptr);
|
||||
if( mxIsSparse(cell_ptr) ){
|
||||
/* Sparse Matrix */
|
||||
ir_ptr = mxGetIr(cell_ptr);
|
||||
jc_ptr = mxGetJc(cell_ptr);
|
||||
if( sizeM == 1 && sizeN != 1 ){
|
||||
/* Row Vector Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
startidx = jc_ptr[j];
|
||||
endidx = jc_ptr[j+1];
|
||||
if( startidx == endidx ){ continue; }
|
||||
sdpa.inputInitYMat( l+1, j+1, j+1, tmp_ptr[startidx]);
|
||||
}
|
||||
} else if( sizeM != 1 && sizeN == 1 ){
|
||||
/* Column Vector Case */
|
||||
endidx = jc_ptr[sizeN];
|
||||
for(idx = 0; idx < endidx; idx++){
|
||||
i = ir_ptr[idx];
|
||||
sdpa.inputInitYMat( l+1, i+1, i+1, tmp_ptr[idx]);
|
||||
}
|
||||
} else {
|
||||
/* Matrix Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
startidx = jc_ptr[j];
|
||||
endidx = jc_ptr[j+1];
|
||||
if( startidx == endidx ){ continue; }
|
||||
for(idx = startidx; idx < endidx; idx++){
|
||||
i = ir_ptr[idx];
|
||||
if( i <= j ){
|
||||
sdpa.inputInitYMat( l+1, i+1, j+1, tmp_ptr[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Dense Matrix */
|
||||
if( sdpa.getBlockType(l+1) == SDPA::SDP ){
|
||||
/* Full Matrix */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
for(i = 0; i < sizeM; i++){
|
||||
if( i <= j ){
|
||||
if( tmp_ptr[j * sizeN + i] != 0 ){
|
||||
sdpa.inputInitYMat( l+1, i+1, j+1,
|
||||
tmp_ptr[j * sizeN + i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Diagonal Matrix */
|
||||
if( sizeM == 1 && sizeN != 1 ){
|
||||
/* Row Vector Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
if( tmp_ptr[j] != 0 ){
|
||||
sdpa.inputInitYMat( l+1, j+1, j+1, tmp_ptr[j]);
|
||||
}
|
||||
}
|
||||
} else if( sizeM != 1 && sizeN == 1 ){
|
||||
/* Column Vector Case */
|
||||
for(i = 0; i < sizeM; i++){
|
||||
if( tmp_ptr[i] != 0 ){
|
||||
sdpa.inputInitYMat( l+1, i+1, i+1, tmp_ptr[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Matrix Case */
|
||||
for(j = 0; j < sizeN; j++){
|
||||
if( tmp_ptr[j * sizeN + j] != 0 ){
|
||||
sdpa.inputInitYMat( l+1, j+1, j+1,
|
||||
tmp_ptr[j * sizeN + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cell_index++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*** Solve SDP ***/
|
||||
sdpa.initializeSolve();
|
||||
sdpa.solve();
|
||||
/*** Dimacs Error Information ****/
|
||||
if (nDimacs != 0) {
|
||||
field_ptr = mxCreateNumericMatrix(6,1,mxDOUBLE_CLASS,mxREAL);
|
||||
double dimacs_error[7];
|
||||
sdpa.getDimacsError(dimacs_error);
|
||||
double* dimacs_store = mxGetPr(field_ptr);
|
||||
if (sdpa.judgeDimacsAvailability() == false) {
|
||||
for (int i=0; i<=6; i++) {
|
||||
dimacs_store[i] = 0.0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i=1; i<=6; i++) {
|
||||
dimacs_store[i-1] = dimacs_error[i];
|
||||
}
|
||||
}
|
||||
mxSetField(INFO_ptr, 0, "dimacs", field_ptr);
|
||||
}
|
||||
/**** Set output values to arguments ****/
|
||||
/* Optimal value of Primal objective */
|
||||
objVal_ptr[0] = sdpa.getPrimalObj();
|
||||
/* Optimal value of Dual objective */
|
||||
objVal_ptr[1] = sdpa.getDualObj();
|
||||
/* Optimal value for xVec */
|
||||
tmp_ptr = sdpa.getResultXVec();
|
||||
if( tmp_ptr != NULL ){
|
||||
for(k = 0; k < mDIM; k++){
|
||||
x_ptr[k] = tmp_ptr[k];
|
||||
}
|
||||
}
|
||||
/* Optimal value for XMat */
|
||||
cell_index = 0;
|
||||
result_ptr = sdpa.getResultXMat(1);
|
||||
if (result_ptr == NULL) {
|
||||
rMessage("XMat is not computed by XPrint, and XMat will be empty matrix.");
|
||||
}
|
||||
for(l = 0; l < nBLOCK; l++){
|
||||
result_ptr = sdpa.getResultXMat(l+1);
|
||||
if (result_ptr == NULL) {
|
||||
cell_ptr = mxCreateDoubleMatrix(0, 0, mxREAL);
|
||||
mxSetCell(X_ptr, cell_index++, mxDuplicateArray(cell_ptr));
|
||||
continue;
|
||||
}
|
||||
size = sdpa.getBlockSize(l+1);
|
||||
if( sdpa.getBlockType(l+1) == SDPA:: SDP){
|
||||
sizeM = size;
|
||||
sizeN = size;
|
||||
} else {
|
||||
sizeM = 1;
|
||||
sizeN = abs(size);
|
||||
}
|
||||
cell_ptr = mxCreateDoubleMatrix(sizeM, sizeN, mxREAL);
|
||||
tmp_ptr = mxGetPr(cell_ptr);
|
||||
idx = 0;
|
||||
result_ptr = sdpa.getResultXMat(l+1);
|
||||
if( size >= 0 ){
|
||||
for(j = 0; j < sizeN; j++){
|
||||
for(i = 0; i < sizeM; i++){
|
||||
tmp_ptr[idx++] = result_ptr[j + sizeN * i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(idx = 0; idx < sizeN; idx++){
|
||||
tmp_ptr[idx] = result_ptr[idx];
|
||||
}
|
||||
}
|
||||
mxSetCell(X_ptr, cell_index++, mxDuplicateArray(cell_ptr));
|
||||
}
|
||||
/* Optimal value for YMat */
|
||||
result_ptr = sdpa.getResultYMat(1);
|
||||
if (result_ptr == NULL) {
|
||||
rMessage("YMat is not computed by YPrint, and YMat will be empty matrix.");
|
||||
}
|
||||
cell_index = 0;
|
||||
for(l = 0; l < nBLOCK; l++){
|
||||
result_ptr = sdpa.getResultYMat(l+1);
|
||||
if (result_ptr == NULL) {
|
||||
cell_ptr = mxCreateDoubleMatrix(0, 0, mxREAL);
|
||||
mxSetCell(Y_ptr, cell_index++, mxDuplicateArray(cell_ptr));
|
||||
continue;
|
||||
}
|
||||
size = sdpa.getBlockSize(l+1);
|
||||
if( sdpa.getBlockType(l+1) == SDPA:: SDP){
|
||||
sizeM = size;
|
||||
sizeN = size;
|
||||
} else {
|
||||
sizeM = 1;
|
||||
sizeN = abs(size);
|
||||
}
|
||||
cell_ptr = mxCreateDoubleMatrix(sizeM, sizeN, mxREAL);
|
||||
tmp_ptr = mxGetPr(cell_ptr);
|
||||
idx = 0;
|
||||
result_ptr = sdpa.getResultYMat(l+1);
|
||||
if( size >= 0 ){
|
||||
for(j = 0; j < sizeN; j++){
|
||||
for(i = 0; i < sizeM; i++){
|
||||
tmp_ptr[idx++] = result_ptr[j + sizeN * i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(idx = 0; idx < sizeN; idx++){
|
||||
tmp_ptr[idx] = result_ptr[idx];
|
||||
}
|
||||
}
|
||||
mxSetCell(Y_ptr, cell_index++, mxDuplicateArray(cell_ptr));
|
||||
}
|
||||
/* Phase information */
|
||||
field_ptr = mxCreateString(szPhase[sdpa.getPhaseValue()]);
|
||||
mxSetField(INFO_ptr, 0, "phasevalue", field_ptr);
|
||||
/* Iteration */
|
||||
field_ptr = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||
*mxGetPr(field_ptr) = (double)sdpa.getIteration();
|
||||
mxSetField(INFO_ptr, 0, "iteration", field_ptr);
|
||||
/* close output file */
|
||||
time(<ime);
|
||||
strcpy(string_time,ctime(<ime));
|
||||
string_time[strlen(string_time)-1]='\0';
|
||||
if (fp) {
|
||||
fprintf(fp,"SDPA-C end at [%s]\n",string_time);
|
||||
}
|
||||
if (fpResult) {
|
||||
fprintf(fpResult,"SDPA-C end at [%s]\n",string_time);
|
||||
}
|
||||
|
||||
if( nOutfile ){
|
||||
fclose(fp);
|
||||
}
|
||||
if (fpResult != NULL) {
|
||||
fclose(fpResult);
|
||||
}
|
||||
/*** Free allocated memory ****/
|
||||
mxFree(subscript);
|
||||
sdpa.finalize();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Matlab gateway function
|
||||
*/
|
||||
void mexFunction(int nlhs, mxArray *plhs[],
|
||||
int nrhs, const mxArray *prhs[])
|
||||
{
|
||||
/* Decleration of variables */
|
||||
|
||||
double
|
||||
*mDIM_ptr,
|
||||
*nBLOCK_ptr,
|
||||
*bLOCKsTRUCT_ptr,
|
||||
*c_ptr,
|
||||
*x_ptr,
|
||||
*objVal_ptr,
|
||||
*x0_ptr;
|
||||
|
||||
mxArray
|
||||
*F_ptr,
|
||||
*X_ptr,
|
||||
*Y_ptr,
|
||||
*X0_ptr,
|
||||
*Y0_ptr,
|
||||
*OPTION_ptr,
|
||||
*INFO_ptr;
|
||||
|
||||
int IniPt;
|
||||
|
||||
const char *fnames[] = {
|
||||
"phasevalue",
|
||||
"iteration",
|
||||
"dimacs",
|
||||
"cpusec"
|
||||
};
|
||||
|
||||
/*
|
||||
* check arguments
|
||||
*/
|
||||
if( nrhs != 9 ){
|
||||
mexErrMsgTxt("Input arguments must be 9.");
|
||||
}
|
||||
|
||||
/* Get the pointer of input variables */
|
||||
mDIM_ptr = mxGetPr(prhs[0]);
|
||||
nBLOCK_ptr = mxGetPr(prhs[1]);
|
||||
bLOCKsTRUCT_ptr = mxGetPr(prhs[2]);
|
||||
c_ptr = mxGetPr(prhs[3]);
|
||||
F_ptr = (mxArray*)prhs[4];
|
||||
x0_ptr = mxGetPr(prhs[5]);
|
||||
X0_ptr = (mxArray*)prhs[6];
|
||||
Y0_ptr = (mxArray*)prhs[7];
|
||||
OPTION_ptr = (mxArray*)prhs[8];
|
||||
|
||||
if( mxIsEmpty(prhs[5]) /* x0 */
|
||||
|| mxIsEmpty(prhs[6]) /* X0 */
|
||||
|| mxIsEmpty(prhs[7]) /* Y0 */
|
||||
){
|
||||
/* nouse of Initial Point*/
|
||||
IniPt = 0;
|
||||
} else {
|
||||
/* use of Initial Point */
|
||||
IniPt = 1;
|
||||
/* check of argument dimensions */
|
||||
/* if(*mDIM_ptr != mxGetM(prhs[5]) || !mxIsDouble(prhs[5]))
|
||||
mexErrMsgTxt("x0 must be (mDIM x 1) column vector of double");
|
||||
if( *nBLOCK_ptr != sizeM_X0 || 1 != sizeN_X0 || !mxIsCell(prhs[6]))
|
||||
mexErrMsgTxt("X0 must be (nBLOCK x 1) cell array");
|
||||
if( *nBLOCK_ptr != sizeM_Y0 || 1 != sizeN_Y0 || !mxIsCell(prhs[7]))
|
||||
|
||||
mexErrMsgTxt("Y0 must be (nBLOCK x 1) cell array");*/
|
||||
}
|
||||
/* Create cellarrays for the output variables */
|
||||
plhs[0] = mxCreateDoubleMatrix(1,2,mxREAL);
|
||||
plhs[1] = mxCreateDoubleMatrix((int) *mDIM_ptr,1,mxREAL);
|
||||
plhs[2] = mxCreateCellMatrix((int) *nBLOCK_ptr,1);
|
||||
plhs[3] = mxCreateCellMatrix((int) *nBLOCK_ptr,1);
|
||||
plhs[4] = mxCreateStructMatrix(1,1,4,fnames);
|
||||
|
||||
//Get the pointer of output variables
|
||||
objVal_ptr = mxGetPr(plhs[0]);
|
||||
x_ptr = mxGetPr(plhs[1]);
|
||||
X_ptr = plhs[2];
|
||||
Y_ptr = plhs[3];
|
||||
INFO_ptr = plhs[4];
|
||||
|
||||
/* Call sdpasolver here */
|
||||
sdpasolver(mDIM_ptr,
|
||||
nBLOCK_ptr,
|
||||
bLOCKsTRUCT_ptr,
|
||||
c_ptr,
|
||||
F_ptr,
|
||||
x0_ptr,
|
||||
X0_ptr,
|
||||
Y0_ptr,
|
||||
OPTION_ptr,
|
||||
IniPt,
|
||||
objVal_ptr,
|
||||
x_ptr,
|
||||
X_ptr,
|
||||
Y_ptr,
|
||||
INFO_ptr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* End of File
|
||||
*/
|
||||
Vendored
+233
@@ -0,0 +1,233 @@
|
||||
function OPTION=paramC(OPTION)
|
||||
%
|
||||
% Create SDPA-C parameters.
|
||||
% If there is no argument, default parameters are returned.
|
||||
%
|
||||
% OPTION=paramC % for default parameter
|
||||
% or
|
||||
% OPTION=paramC(field1,value1,field2,value2,....)
|
||||
%
|
||||
% <INPUT>
|
||||
% - field?: string : field name
|
||||
% - value?: numeric or string :
|
||||
%
|
||||
% <OUTPUT>
|
||||
% - OPTION: structure data: each field is as follows:
|
||||
% * maxIteration : The maximum number of iterations.
|
||||
% * epsilonStar : The accuracy of an approximate optimal solution
|
||||
% for primal and dual SDP.
|
||||
% * lambdaStar : An initial point.
|
||||
% * omegaStar : The search region for an optimal solution.
|
||||
% * lowerBound : Lower bound of the minimum objective value of
|
||||
% the primal SDP.
|
||||
% * upperBound : Upper bound of the maximum objective value of
|
||||
% the dual SDP
|
||||
% * betaStar : The parameter for controlling the search direction
|
||||
% if the current point is feasible.
|
||||
% * betaBar : The parameter for controlling the search direction
|
||||
% if the current point is infeasible.
|
||||
% * gammaStar : A reduction factor for the primal and dual step
|
||||
% lengths.
|
||||
% * epsilonDash : The relative accuracy of an approximate optimal
|
||||
% solution between primal and dual SDP.
|
||||
% * isSymmetric : The flag for the checking the symmetricity of input
|
||||
% matrices. (0 => no check, 1=> check)
|
||||
% * isDimacs : The flag to compute DIMACS ERROR
|
||||
% (0 => no computation, 1=> computation)
|
||||
% * xPrint : (default %+8.3e, NOPRINT skips printout)
|
||||
% * XPrint : (default %+8.3e, NOPRINT skips printout)
|
||||
% * YPrint : (default %+8.3e, NOPRINT skips printout)
|
||||
% * infPrint : (default %+10.16e, NOPRINT skips printout)
|
||||
% * print : Destination of file output. the default setting is
|
||||
% stdout by 'display'.
|
||||
% If print is set 'no' or empty, no message
|
||||
% is print out
|
||||
% * resultFile : Destination of detail file output
|
||||
% * NumThreads : Number of Threads for internal computation
|
||||
|
||||
% This file is a component of SDPA
|
||||
% Copyright (C) 2004-2013 SDPA Project
|
||||
%
|
||||
% This program is free software; you can redistribute it and/or modify
|
||||
% it under the terms of the GNU General Public License as published by
|
||||
% the Free Software Foundation; either version 2 of the License, or
|
||||
% (at your option) any later version.
|
||||
%
|
||||
% This program is distributed in the hope that it will be useful,
|
||||
% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
% GNU General Public License for more details.
|
||||
%
|
||||
% You should have received a copy of the GNU General Public License
|
||||
% along with this program; if not, write to the Free Software
|
||||
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
%
|
||||
% SDPA-M: $Revision: 6.2 $
|
||||
% $Id: param.m,v 6.2 2005/05/28 02:36:40 drophead Exp $
|
||||
|
||||
% create default OPTION
|
||||
OPTION0.maxIteration = 100;
|
||||
OPTION0.epsilonStar = 1.0E-7;
|
||||
OPTION0.lambdaStar = 1.0E2;
|
||||
OPTION0.omegaStar = 2.0;
|
||||
OPTION0.lowerBound = -1.0E5;
|
||||
OPTION0.upperBound = 1.0E5;
|
||||
OPTION0.betaStar = 0.1;
|
||||
OPTION0.betaBar = 0.3;
|
||||
OPTION0.gammaStar = 0.9;
|
||||
OPTION0.epsilonDash = 1.0E-7;
|
||||
OPTION0.isSymmetric = 0;
|
||||
OPTION0.isDimacs = 0;
|
||||
OPTION0.xPrint = '%+8.3e';
|
||||
OPTION0.XPrint = '%+8.3e';
|
||||
OPTION0.YPrint = '%+8.3e';
|
||||
OPTION0.infPrint = '%+16.10e';
|
||||
OPTION0.print = 'display';
|
||||
OPTION0.resultFile = '';
|
||||
try
|
||||
OPTION0.NumThreads = maxNumCompThreads; % Max Avialable Number
|
||||
catch
|
||||
fprintf(['Function maxNumCompThreads is not found, NumThreads ' ...
|
||||
'is set as 1.\n']);
|
||||
OPTION0.NumThreads = 1;
|
||||
end
|
||||
|
||||
|
||||
OPTION0.aggConeSize = [];
|
||||
|
||||
if (nargin == 0) || isempty(OPTION)
|
||||
OPTION = OPTION0;
|
||||
return
|
||||
else
|
||||
if ~isfield(OPTION,'maxIteration')
|
||||
OPTION.maxIteration=OPTION0.maxIteration;
|
||||
elseif ~isnumeric(OPTION.maxIteration)
|
||||
error('OPTION.maxIteration must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'epsilonStar')
|
||||
OPTION.epsilonStar=OPTION0.epsilonStar;
|
||||
elseif ~isnumeric(OPTION.epsilonStar)
|
||||
error('epsilonStar must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'lambdaStar')
|
||||
OPTION.lambdaStar=OPTION0.lambdaStar;
|
||||
elseif ~isnumeric(OPTION.lambdaStar)
|
||||
error('OPTION.lambdaStar must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'omegaStar')
|
||||
OPTION.omegaStar=OPTION0.omegaStar;
|
||||
elseif ~isnumeric(OPTION.omegaStar)
|
||||
error('OPTION.omegaStar must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'lowerBound')
|
||||
OPTION.lowerBound=OPTION0.lowerBound;
|
||||
elseif ~isnumeric(OPTION.lowerBound)
|
||||
error('OPTION.lowerBound must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'upperBound')
|
||||
OPTION.upperBound=OPTION0.upperBound;
|
||||
elseif ~isnumeric(OPTION.upperBound)
|
||||
error('OPTION.upperBound must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'betaStar')
|
||||
OPTION.betaStar=OPTION0.betaStar;
|
||||
elseif ~isnumeric(OPTION.betaStar)
|
||||
error('OPTION.beaStar must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'betaBar')
|
||||
OPTION.betaBar=OPTION0.betaBar;
|
||||
elseif ~isnumeric(OPTION.betaBar)
|
||||
error('OPTION.betaBar must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'gammaStar')
|
||||
OPTION.gammaStar=OPTION0.gammaStar;
|
||||
elseif ~isnumeric(OPTION.gammaStar)
|
||||
error('OPTION.gammaStar must be numeric.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'epsilonDash')
|
||||
OPTION.epsilonDash=OPTION0.epsilonDash;
|
||||
elseif ~isnumeric(OPTION.epsilonDash)
|
||||
error('OPTION.epsilonDash must be numeric.');
|
||||
end
|
||||
%
|
||||
if isfield(OPTION,'searchDir')
|
||||
disp('Parameter *searchDir* is no longer supported.');
|
||||
disp('HRVW/KSH/M is automatically used.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'isSymmetric')
|
||||
OPTION.isSymmetric=OPTION0.isSymmetric;
|
||||
elseif ~isnumeric(OPTION.isSymmetric) || ((OPTION.isSymmetric~=0) && (OPTION.isSymmetric~=1))
|
||||
error('OPTION.isSymmetric must be 0 or 1.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'isDimacs')
|
||||
OPTION.isDimacs=OPTION0.isDimacs;
|
||||
elseif ~isnumeric(OPTION.isDimacs) || ((OPTION.isDimacs~=0) && (OPTION.isDimacs~=1))
|
||||
error('OPTION.isDimacs must be 0 or 1.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'XPrint')
|
||||
OPTION.XPrint=OPTION0.XPrint;
|
||||
elseif ~ischar(OPTION.XPrint)
|
||||
error('OPTION.XPrint must be string.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'YPrint')
|
||||
OPTION.YPrint=OPTION0.YPrint;
|
||||
elseif ~ischar(OPTION.YPrint)
|
||||
error('OPTION.YPrint must be string for printf.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'infPrint')
|
||||
OPTION.infPrint=OPTION0.infPrint;
|
||||
elseif ~ischar(OPTION.infPrint)
|
||||
error('OPTION.infPrint must be string for printf.');
|
||||
end
|
||||
%
|
||||
if isfield(OPTION,'print') && ...
|
||||
(isempty(OPTION.print) || length(OPTION.print) == 0)
|
||||
OPTION.print = 'no';
|
||||
end
|
||||
if ~isfield(OPTION,'print')
|
||||
OPTION.print=OPTION0.print;
|
||||
elseif ~ischar(OPTION.print)
|
||||
disp('*** OPTION.print must be string for FILE. ***');
|
||||
disp(' "display" is for stdout.');
|
||||
disp(' "no" or empty is for skip message.');
|
||||
disp(' filename is filename in which message will be written.');
|
||||
error('*** OPTION.print must be string for FILE. ***');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'resultFile') || isempty(OPTION.resultFile)
|
||||
OPTION.resultFile=OPTION0.resultFile;
|
||||
elseif ~ischar(OPTION.resultFile)
|
||||
error('OPTION.resultFile must be string.');
|
||||
end
|
||||
%
|
||||
if ~isfield(OPTION,'NumThreads')
|
||||
OPTION.NumThreads=OPTION0.NumThreads;
|
||||
elseif ~isnumeric(OPTION.NumThreads)
|
||||
error('OPTION.NumThreads must be positive integer.');
|
||||
end
|
||||
|
||||
if ~isfield(OPTION,'aggConeSize')
|
||||
OPTION.aggConeSize = OPTION0.aggConeSize;
|
||||
elseif (~isempty(OPTION.aggConeSize)) && ...
|
||||
((~isnumeric(OPTION.aggConeSize)) || (OPTION.aggConeSize <=0))
|
||||
error('OPTION.aggConeSize must be a positive integer.');
|
||||
end
|
||||
end
|
||||
|
||||
return
|
||||
|
||||
% End of File
|
||||
Vendored
+81
@@ -0,0 +1,81 @@
|
||||
function [objVal,x,X,Y,INFO]=sdpamC(mDIM,nBLOCK,bLOCKsTRUCT,c,F,...
|
||||
x0,X0,Y0,OPTION)
|
||||
%
|
||||
% Compute the solution of standard SDP.
|
||||
% Since some of input arguments are optional, sdpam can be
|
||||
% overloaded as below.
|
||||
%
|
||||
% [objVal,x,X,Y,INFO] = sdpamC(mDIM,nBLOCK,bLOCKsTRUCT,c,F,
|
||||
% x0,X0,Y0,OPTION);
|
||||
%
|
||||
% <INPUT>
|
||||
% - mDIM : integer ; number of primal variables
|
||||
% - nBLOCK : integer ; number of blocks of F
|
||||
% - bLOCKsTRUCT: vector ; represetns the block structure of F
|
||||
% - c : vector ; coefficient vector
|
||||
% - F : cell array; coefficient matrices
|
||||
% - x0,X0,Y0 : cell array; initial point
|
||||
% (NOTE: In SDPA-C, initial point is ignored.)
|
||||
% - OPTION : structure ; options
|
||||
%
|
||||
% <OUTPUT>
|
||||
% - objVal: [objValP objValD]; optimal value of P and D
|
||||
% - x : vector ; optimal solution
|
||||
% - X,Y : cell arrray ; optimal solutions
|
||||
% - INFO : structure ; infomation of the solution
|
||||
%
|
||||
|
||||
% This file is a component of SDPA
|
||||
% Copyright (C) 2004-2013 SDPA Project
|
||||
%
|
||||
% This program is free software; you can redistribute it and/or modify
|
||||
% it under the terms of the GNU General Public License as published by
|
||||
% the Free Software Foundation; either version 2 of the License, or
|
||||
% (at your option) any later version.
|
||||
%
|
||||
% This program is distributed in the hope that it will be useful,
|
||||
% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
% GNU General Public License for more details.
|
||||
%
|
||||
% You should have received a copy of the GNU General Public License
|
||||
% along with this program; if not, write to the Free Software
|
||||
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
%
|
||||
% SDPA-M: $Revision: 6.2 $
|
||||
% $Id: sdpam.m,v 6.2 2005/05/28 02:36:40 drophead Exp $
|
||||
|
||||
t = cputime;
|
||||
|
||||
if (nargin < 5 || nargin > 9)
|
||||
error('incorrect number of input arguments')
|
||||
elseif nargin == 5
|
||||
% make initial points empty
|
||||
x0=[];X0=[];Y0=[];
|
||||
% load default parameters
|
||||
OPTION=paramC;
|
||||
% solve by SDPA
|
||||
[objVal,x,X,Y,INFO]=mexsdpaC(mDIM,nBLOCK,bLOCKsTRUCT,...
|
||||
c,F,x0,X0,Y0,OPTION);
|
||||
elseif nargin == 6
|
||||
% use OPTION given by arguments
|
||||
OPTION=paramC(x0);
|
||||
% make initial points empty
|
||||
x0=[];X0=[];Y0=[];
|
||||
[objVal,x,X,Y,INFO]=mexsdpaC(mDIM,nBLOCK,bLOCKsTRUCT,...
|
||||
c,F,x0,X0,Y0,OPTION);
|
||||
elseif nargin == 8
|
||||
% load default parameters
|
||||
OPTION=paramC;
|
||||
%solve by SDPA
|
||||
[objVal,x,X,Y,INFO]=mexsdpaC(mDIM,nBLOCK,bLOCKsTRUCT,...
|
||||
c,F,x0,X0,Y0,OPTION);
|
||||
elseif nargin == 9
|
||||
OPTION=paramC(OPTION);
|
||||
% solve by SDPA
|
||||
[objVal,x,X,Y,INFO]=mexsdpaC(mDIM,nBLOCK,bLOCKsTRUCT,...
|
||||
c,F,x0,X0,Y0,OPTION);
|
||||
end
|
||||
INFO.cpusec = cputime-t;
|
||||
|
||||
% End of File
|
||||
Vendored
+382
@@ -0,0 +1,382 @@
|
||||
function [x,y,info]=sedumiwrapC(A,b,c,K,pars,OPTION);
|
||||
|
||||
%
|
||||
% SeDuMi wrapper for SDPA
|
||||
%
|
||||
% [x,y,info]=sedumiwrapC(A,b,c,K,pars,OPTION);
|
||||
% or
|
||||
% [x,y,info]=sedumiwrapC(A,b,c,K); % with SDPA-M default parameter
|
||||
%
|
||||
% Note :
|
||||
% 'A', in each SDP block, only upper triangle part is used.
|
||||
% 'K' can include only 'f'(free) 'l'(linear) 's'(SDP) cones.
|
||||
% 'pars' information is NOT used (just for SeDuMi compatibility)
|
||||
% 'OPTION' is option structure for SDPA-M (for details, try 'help param')
|
||||
% 'info' information is based on SDPA-M
|
||||
%
|
||||
% This file is a component of SDPA
|
||||
% Copyright (C) 2004-2013 SDPA Project
|
||||
%
|
||||
% This program is free software; you can redistribute it and/or modify
|
||||
% it under the terms of the GNU General Public License as published by
|
||||
% the Free Software Foundation; either version 2 of the License, or
|
||||
% (at your option) any later version.
|
||||
%
|
||||
% This program is distributed in the hope that it will be useful,
|
||||
% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
% GNU General Public License for more details.
|
||||
%
|
||||
% You should have received a copy of the GNU General Public License
|
||||
% along with this program; if not, write to the Free Software
|
||||
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
%
|
||||
% SDPA-M: $Revision: 7.3 $
|
||||
|
||||
|
||||
t = cputime;
|
||||
|
||||
fprintf('-SeDuMi Wrapper for SDPA-C Start-\n');
|
||||
|
||||
if (nargin < 4 || nargin > 6)
|
||||
error('incorrect number of input arguments')
|
||||
end
|
||||
if nargin >= 5
|
||||
if isfield(OPTION,'print') && ~isempty(OPTION.print)
|
||||
fprintf('Note: pars information [5th argument] is not used\n');
|
||||
end
|
||||
end
|
||||
if nargin < 6
|
||||
OPTION = paramC;
|
||||
else
|
||||
OPTION = paramC(OPTION);
|
||||
end
|
||||
|
||||
if isfield(K,'q') && ~isempty(K.q)
|
||||
error('Current Wrapper cannot handle K.q');
|
||||
end
|
||||
|
||||
if isfield(K,'r') && ~isempty(K.r)
|
||||
error('Current Wrapper cannot handle K.r');
|
||||
end
|
||||
|
||||
if size(b,2) ~= 1
|
||||
% fprintf('Transposing b to a column vector');
|
||||
b = b';
|
||||
end
|
||||
if size(b,2) ~= 1
|
||||
error('b must be a vector');
|
||||
end
|
||||
|
||||
if size(c,2) ~= 1
|
||||
% fprintf('Transposing c to a column vector\n');
|
||||
c = c';
|
||||
end
|
||||
if size(c,2) ~= 1
|
||||
error('c must be a vector');
|
||||
end
|
||||
|
||||
%%%%%
|
||||
% Constructing at least one SDP cone if necesary
|
||||
if (~isfield(K,'s')) || (isempty(K.s))
|
||||
[K] = LPtoLP_SDP(K);
|
||||
end
|
||||
%%%%%
|
||||
|
||||
totalLength = 0;
|
||||
Kf = 0;
|
||||
if isfield(K,'f') && ~isempty(K.f)
|
||||
totalLength = totalLength + K.f;
|
||||
Kf = K.f;
|
||||
end
|
||||
if isfield(K,'l') && ~isempty(K.l)
|
||||
totalLength = totalLength + K.l;
|
||||
else
|
||||
K.l = 0;
|
||||
end
|
||||
if isfield(K,'s') && ~isempty(K.s)
|
||||
if size(K.s,2) ~= 1
|
||||
% fprintf('Transposing K.s to a column vector\n');
|
||||
K.s = K.s';
|
||||
end
|
||||
Ks = sum(K.s .* K.s);
|
||||
totalLength = totalLength + Ks;
|
||||
else
|
||||
error('Cannot handle empty K.s');
|
||||
end
|
||||
m = size(b,1);
|
||||
n = size(c,1);
|
||||
|
||||
[mA,nA] = size(A);
|
||||
if (m~=mA || n~=nA) && (m~=nA || n~=mA)
|
||||
fprintf('Inconsistent Size of A,b,c\n');
|
||||
fprintf('size(A) = [%d,%d], size(b) = %d, size(c) = %d\n',...
|
||||
mA,nA, m,n);
|
||||
error('Cannot continue...');
|
||||
end
|
||||
|
||||
if (n~=totalLength)
|
||||
fprintf('Inconsistent Size of c and K\n');
|
||||
fprintf('size(c) = %d, totalSize(K) = %d\n',...
|
||||
n, totalLength);
|
||||
error('Cannot continue...');
|
||||
end
|
||||
|
||||
if ~issparse(A)
|
||||
if isfield(OPTION,'print') && ~isempty(OPTION.print)
|
||||
fprintf('Converting A from dense to sparse\n');
|
||||
end
|
||||
A = sparse(A);
|
||||
end
|
||||
|
||||
if issparse(b)
|
||||
% fprintf('Converting b from sparse to dense\n');
|
||||
b = full(b);
|
||||
end
|
||||
|
||||
if ~issparse(c)
|
||||
% fprintf('Converting c from dense to sparse\n');
|
||||
c = sparse(c);
|
||||
end
|
||||
|
||||
if issparse(K.s)
|
||||
% fprintf('Converting K.s from sparse to dense\n');
|
||||
K.s = full(K.s);
|
||||
end
|
||||
|
||||
if Kf ~= 0
|
||||
if isfield(OPTION,'print') && ~isempty(OPTION.print)
|
||||
fprintf(['Free Variables are divided into positive and ' ...
|
||||
'negative part of LP cone\n']);
|
||||
end
|
||||
Af = A(:,1:Kf);
|
||||
Kl = K.l;
|
||||
Al = A(:,Kf+1:Kf+Kl);
|
||||
As = A(:,Kf+Kl+1:Kf+Kl+Ks);
|
||||
Anew = [Af, -Af, Al, As];
|
||||
|
||||
cf = c(1:Kf);
|
||||
cl = c(Kf+1:Kf+Kl);
|
||||
cs = c(Kf+Kl+1:Kf+Kl+Ks);
|
||||
cnew = [cf; -cf; cl; cs];
|
||||
|
||||
Knew.l = 2*Kf + Kl;
|
||||
Knew.s = K.s;
|
||||
|
||||
A = Anew;
|
||||
c = cnew;
|
||||
K = Knew;
|
||||
|
||||
clear Af;
|
||||
clear Al;
|
||||
clear As;
|
||||
clear Anew;
|
||||
clear cf;
|
||||
clear cl;
|
||||
clear cs;
|
||||
clear cnew;
|
||||
clear Knew;
|
||||
end
|
||||
|
||||
if isfield(K,'s') && ~isempty(K.s)
|
||||
if size(K.s,2) ~= 1
|
||||
K.s = Ks';
|
||||
end
|
||||
end
|
||||
|
||||
%%%%%
|
||||
% Aggregating small SDP cones into larger SDP cones
|
||||
aggSW = 0;
|
||||
minNoSDPcones = 3;
|
||||
if (isfield(OPTION,'aggConeSize')) && (~isempty(OPTION.aggConeSize)) && (isnumeric(OPTION.aggConeSize)) && ...
|
||||
((OPTION.aggConeSize > 0)) && (length(K.s') > minNoSDPcones) && (length(find(K.s' < OPTION.aggConeSize)) > minNoSDPcones)
|
||||
fprintf('OPTION.aggConeSize = %d\n',OPTION.aggConeSize)
|
||||
K0 = K;
|
||||
aggSW = 1;
|
||||
[A,c,K1] = aggSDPcones(A,c,K,OPTION.aggConeSize);
|
||||
A = sparse(A);
|
||||
c = sparse(c);
|
||||
K = K1;
|
||||
end
|
||||
%%%%%
|
||||
|
||||
|
||||
% A should be transposed when passed to mex
|
||||
[mA,nA] = size(A);
|
||||
if mA ~= K.l + sum(K.s.*K.s)
|
||||
A = A';
|
||||
end
|
||||
% fprintf('size(A) = (%d,%d)\n',size(A,2),size(A,1));
|
||||
% fprintf('length(K.s) = %d\n',length(K.s));
|
||||
|
||||
[x,y,info] = mexSedumiWrapC(A,b,c,K,OPTION);
|
||||
|
||||
%%%%%
|
||||
% Retrieving the origianl primal SDP cone variables
|
||||
if aggSW == 1
|
||||
if (isfield(K,'l')) && (~isempty(K.l)) && (K.l > 0)
|
||||
xSDP = x(K.l+1:size(x,1),1);
|
||||
xLP = x(1:K.l,1);
|
||||
[xSDP] = mexDisAggSDPsol(xSDP,K0.s,K1.s);
|
||||
x = [xLP; xSDP];
|
||||
else
|
||||
[x] = mexDisAggSDPsol(x,K0.s,K1.s);
|
||||
end
|
||||
end
|
||||
%%%%%
|
||||
|
||||
if Kf ~=0
|
||||
xlength = size(x);
|
||||
xnew = x(1:Kf) - x(Kf+1:Kf+Kf);
|
||||
xnew = [xnew; x(Kf+Kf+1:xlength)];
|
||||
x = xnew;
|
||||
end
|
||||
|
||||
info.cpusec = cputime-t;
|
||||
% if isfield(OPTION,'print') && ~isempty(OPTION.print)
|
||||
fprintf('-SeDuMi Wrapper for SDPA-C End-\n');
|
||||
% end
|
||||
|
||||
% End of File
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
function [K] = LPtoLP_SDP(K)
|
||||
|
||||
if isfield(K,'q') && ~isempty(K.q)
|
||||
error('Current Wrapper cannot handle K.q');
|
||||
end
|
||||
|
||||
if isfield(K,'r') && ~isempty(K.r)
|
||||
error('Current Wrapper cannot handle K.r');
|
||||
end
|
||||
|
||||
if isfield(K,'s') && ~isempty(K.s)
|
||||
return;
|
||||
elseif ~isfield(K,'l') || isempty(K.l)
|
||||
error('Both LP and SDP cones are empty, so the problem can not be solved');
|
||||
else
|
||||
K.l = K.l-1;
|
||||
if K.l == 0
|
||||
K.l = [];
|
||||
end
|
||||
K.s = 1;
|
||||
end
|
||||
|
||||
return
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
function [A1,c1,K1] = aggSDPcones(A,c,K0,aggConeSize)
|
||||
%
|
||||
% [A1,c1,K1] = aggSDPcones(A,c,K0,aggConeSize)
|
||||
% Input : SeDuMi format
|
||||
% aggConeSize : the block size into which small blocks are converted
|
||||
% Output: Sedumi format with larger SDP cone matrices
|
||||
%
|
||||
|
||||
if (size(K0.s,2) > 1)
|
||||
K0.s = K0.s';
|
||||
end
|
||||
|
||||
if size(A,1) > size(A,2)
|
||||
A = A';
|
||||
end
|
||||
% if size(c,1) < size(c,2)
|
||||
% c = c';
|
||||
% end
|
||||
[m,n] = size(A);
|
||||
%
|
||||
if ~isfield(K0,'f') || isempty(K0.f)
|
||||
fDim = 0;
|
||||
else
|
||||
fDim = K0.f;
|
||||
end
|
||||
%
|
||||
if ~isfield(K0,'l') || isempty(K0.l)
|
||||
ellDim = 0;
|
||||
else
|
||||
ellDim = K0.l;
|
||||
end
|
||||
%
|
||||
if ~isfield(K0,'q')
|
||||
qDim = 0;
|
||||
else
|
||||
if size(K0.q,1) > size(K0.q,2)
|
||||
K0.q = K0.q'; % a row vector
|
||||
end
|
||||
qDim = sum(K0.q);
|
||||
end
|
||||
%
|
||||
if ~isfield(K0,'s') || isempty(K0.s)
|
||||
K1 = K0;
|
||||
A1 = A;
|
||||
c1 = c;
|
||||
return
|
||||
else
|
||||
if size(K0.s,2) > size(K0.s,1)
|
||||
K0.s = K0.s'; % a column vector
|
||||
end
|
||||
sDim = sum(K0.s .* K0.s);
|
||||
end
|
||||
|
||||
nonSDim = fDim+ellDim+qDim;
|
||||
if nonSDim == 0
|
||||
cNonSDP = [];
|
||||
AnonSDP = [];
|
||||
c0SDP = c;
|
||||
A0SDP = A;
|
||||
else
|
||||
cNonSDP = c(1:nonSDim,1);
|
||||
AnonSDP = A(:,1:nonSDim);
|
||||
c0SDP = c(nonSDim+1:n,1);
|
||||
A0SDP = A(:,nonSDim+1:n);
|
||||
end
|
||||
|
||||
K1s = [];
|
||||
coneSize = 0;
|
||||
for p=1:length(K0.s)
|
||||
if (K0.s(p) > aggConeSize)
|
||||
if coneSize > 0
|
||||
K1s = [K1s; coneSize; K0.s(p)];
|
||||
coneSize = 0;
|
||||
else
|
||||
K1s = [K1s; K0.s(p)];
|
||||
coneSize = 0;
|
||||
end
|
||||
elseif ((coneSize + K0.s(p) > aggConeSize))
|
||||
K1s = [K1s; coneSize];
|
||||
coneSize = K0.s(p);
|
||||
elseif ((coneSize + K0.s(p) == aggConeSize))
|
||||
K1s = [K1s; coneSize + K0.s(p)];
|
||||
coneSize = 0;
|
||||
else
|
||||
coneSize = coneSize + K0.s(p);
|
||||
end
|
||||
end
|
||||
if (coneSize > 0)
|
||||
K1s = [K1s; coneSize];
|
||||
end
|
||||
|
||||
K0s = K0.s; % K0.s is a column vector
|
||||
K1 = K0;
|
||||
K1.s = K1s; % K1s is a column vector
|
||||
|
||||
tStart = tic;
|
||||
% C0SDP, K0s and K1s need to be clolumn vector
|
||||
[A1SDP,c1SDP] = mexAggSDPcones(A0SDP,c0SDP',K0s,K1s);
|
||||
tElapsed = toc(tStart);
|
||||
fprintf('Original SDP: the max cone size, the number of cones = %3d, %3d\n',full(max(K0.s)),length(K0.s));
|
||||
fprintf('Transformed SDP: the max cone size, the number of cones = %3d, %3d\n',full(max(K1.s)),length(K1.s));
|
||||
% fprintf('Elapsed time for transformation = %6.2e\n',tElapsed);
|
||||
|
||||
c1SDP = c1SDP';
|
||||
|
||||
A1 = sparse([AnonSDP, A1SDP]);
|
||||
c1 = sparse([cNonSDP;c1SDP]);
|
||||
|
||||
% checkData(A1,b1,c1,K1);
|
||||
|
||||
% sedumi(A1,b1,c1,K1);
|
||||
|
||||
return
|
||||
|
||||
|
||||
Reference in New Issue
Block a user